我想在此处扩展特定代码:
/(?<![@#]|([img]))b(".str_replace(" ", "[-_ ]", $key).")(?![/img])b/i
当前,它检测到@
还是#
是否直接在有关的$key
后面(很好),或者[img]
或[/img]
是否直接在$key
之前/之后(问题)。我想添加一个通配符,以便无法更换[img]
和[/img]
之间的任何地方的$key
,同时仍然保持@
或#
仍然必须直接在$key
后面的事实。我知道不允许通配符在外观上。
这是可能的吗?
编辑:我对自己的代码进行了误解。我意识到,即使[img]
没有先于单词,[/img]
仍然会触发,从而允许@BLUE[/img]
不触发。我希望将#/@
和[img][/img]
之间的案例分开。对此的帮助也将有很大帮助。
基本上,[img]
和[/img]
中的所有内容都将忽略$key
,@$key
和#$key
的preg_replace
。但是,即使是独立的@$key
和#$key
(没有[img]
标签),$key
也不应更换。
使用Lookarounds不是一个好方法
目标是跳过[img]
标签之间的内容,让我们看看:
$result = preg_replace('~[(img|url)].*?[/1](*SKIP)(*FAIL)|(?<![@#])bHELLOb~s',
'GOODBYE', $str);
(*SKIP)
禁止在右侧副本失败时重试符合左侧的字符串部分。
(*FAIL)
迫使模式失败。
由于 [img]
标签总是首先是由模式的第一个分支尝试的,因此模式的第二个分支匹配始终在[img]
标签外的字符串部分。
另一种方式
您可以将您搜索的密钥描述为一个词,该单词是几个[img]..[/img]
和其他不是[img]
标签或关键词的字符:
$pattern = <<<'LOD'
~
(?> # atomic group: all possible content before "HELLO"
(?> # other characters
[^[H]++ # all characters except [ and H
| # OR
[(?!img]|url]) # a [ not followed by img or url
| # OR
BH # an H not preceded by a word boundary
| # OR
H(?!ELLOb) # an H not followed by ELLO and a word boundary
)+
| # OR
[(img|url)].*?[/1] # img or url tags
)*
K # resets all from the match result
(?<![@#])HELLO
~sx
LOD;