我正在尝试创建一个正则表达式,其中它替换未用括号括起来的单词。
这是我目前拥有的:
$this->parsed = preg_replace('/'b(?<!'[)('.preg_quote($word).')'b/','[$1['.implode(",",array_unique($types)).']]',$this->parsed);
其中$word可以是以下之一,"Burkely Mayfair Trunk"或"Trunk"。
它将取代这句话
这个伯克利梅菲尔树干相当不错
为
这个[伯克利梅菲尔[行李箱[产品名称]][产品名称]]很漂亮 好
虽然它应该成为
这个[伯克利梅菲尔树干[产品名称]]相当不错
由于它按最大字符串到最小字符串的顺序进行替换,因此不应在字符串的已替换部分中替换较小的字符串和/或单词部分的双重出现。当它是字符串的第一部分时,它起作用。
当我尝试进行动态后看时,它给出以下错误:"编译失败:回溯断言在偏移量 11 处不是固定长度"。我不知道如何解决这个问题。
有人有什么想法吗?
在又一个早上玩正则表达式之后,我想出了一个非常肮脏的解决方案,它根本不灵活,但适用于我的用例。
$this->parsed = preg_replace('/'b(?!'[(|(('w+)('s|'.))|(('w+)('s|'.)('w+)('s|'.))))('.preg_quote($word).')(?!((('s|'.)('w+))|(('s|'.)('w+)('s|'.)('w+))|)'[)'b/s','[$10['.implode(",",array_unique($types)).']]',$this->parsed);
它基本上所做的是检查没有单词的括号,前面或后面有 1 个单词或 2 个单词,并结合指定的关键字。
不过,很高兴听到是否有人有更好的解决方案。
您可以将
括号内的任何子字符串与'[[^][]*]
模式匹配,然后使用 PCRE 动词(*SKIP)(*FAIL)
删除匹配项,并且仅在任何其他上下文中匹配您的模式:
'[[^][]*](*SKIP)(*FAIL)|your_pattern_here
请参阅正则表达式演示。要跳过成对嵌套方括号内的匹配项,请使用带有子例程的基于回避的正则表达式(请注意,它必须使用捕获组):
(?<skip>'[(?:[^][]++|(?&skip))*])(*SKIP)(*FAIL)|your_pattern_here
查看正则表达式演示
此外,由于您是动态构建模式,因此需要preg_quote
$word
以及分隔符符号(此处为 /
)。
您的解决方案是
$this->parsed = preg_replace(
'/'[[^][]*'[[^][]*]](*SKIP)(*FAIL)|'b(?:' . preg_quote($word, '/') . ')'b/',
'[$0[' . implode(",", array_unique($types)) . ']]',
$this->parsed);
'[[^][]*'[[^][]*]]
正则表达式将匹配所有已用替换模式包装的实例:
-
'[
-[
-
[^][]*
- 除[
和]
以外的0+字符 -
'[
-[
炭 -
[^][]*
- 除[
和]
以外的0+字符 -
]]
-]]
子字符串。