我有以下字符串:
OPEN someone said hello CLOSE im saying hello people OPEN some said hello OPEN they said hello again CLOSE i have to go now though CLOSE hello again!
我正在尝试匹配所有出现的hello(未包含在OPEN 和CLOSE 词中)并将它们替换为换句话说,可能使用正则表达式和 PHP 的 preg_replace
函数(尽管我对其他方法持开放态度,因为我想不出任何方法)。
所以根据上面的字符串,下面的字符串将匹配(我用斜体将它们放在括号中以帮助您区分):
OPEN someone said hello CLOSE im saying (hello) people OPEN some said hello OPEN they said hello again CLOSE i have to go now though CLOSE (hello) again!
不太确定如何进行此操作。
编辑也许这会更好地阐明嵌套结构:
OPEN
text
CLOSE
OPEN
text
OPEN
text
CLOSE
text
CLOSE
正如您从上面看到的,hello 没有被注意到,因为它在 OPEN...CLOSE 中(因此它们被忽略),而其他不会被替换。
最佳答案
Alan 的回答很有效。但是,由于我已经花时间编写它,这里是使用回调函数和 PHP (?R)
递归表达式的另一种方法:
function highlightNonNestedHello($str) {
$re = '/# Two global alternatives. Either...
( # $1: Non-O..C stuff.
(?: # Step through non-O..C chars.
(?!\b(?:OPEN|CLOSE)\b) # If not start of OPEN or CLOSE,
. # then match next char.
)+ # One or more non-O..C chars.
) # End $1:
| # Or...
( # $2: O..C stuff.
\bOPEN\b # Open literal delimiter.
(?R)+ # Recurse overall regex.
\bCLOSE\b # Close literal delimiter.
) # End $1:
/sx';
return preg_replace_callback($re, '_highlightNonNestedHello_cb', $str);
}
function _highlightNonNestedHello_cb($matches) {
// Case 1: Non-O...C stuff. Highlight all "hello".
if ($matches[1]) {
return preg_replace('/\bhello\b/', '(HELLO)', $matches[1]);
}
// Case 2: O...C stuff. Preserve as-is.
return $matches[2];
}
关于php - 替换所有未包含在 OPEN 和 CLOSE 单词中的特定单词?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7577470/