正则表达式:如何不替换任何 html 标签中的特定单词?

Regex: How not to replace specific word in any html tag?

所以假设我有这样的文本:

This is a great test! We're testing something awesome. Click here to <a href="whatever">test it!</a>.

我想给单词 "test" 添加一些颜色,但如果它在 a 标签中则不行。 我试过这样做:

/(?<!href="(.*?)">)test/

但是没用。 它是这样工作的:

/(?<!href="whatever">)test/

但是我当然有很多链接,所以这不是一个选项。

整个代码应该是这样的:

$replacement = preg_replace('/(?<!href="SOLUTION HERE">)test/','<span style="color: #FF0000;">test</span>',$replacement);

预期结果:

This is a great <span style="color: #FF0000;">test</span>! We're <span style="color: #FF0000;">test</span>ing something awesome. Click here to <a href="whatever">test it!</a>.

与 html 字符串交互的快速但不太可靠的方法是使用正则表达式。 DomDocument(或类似文件)专门设计用于解析 html 并且更值得信赖。我将 post 正则表达式方式,如果我可以管理它,我将添加 DomDocument 方式。

(*SKIP)(*FAIL) 允许您 match/consume 并取消子字符串的资格,然后在管道之后为您实际要替换的子字符串编写模式。

模式:~(?:<[^>]*>.*?</[^>]*>(*SKIP)(*FAIL))|\btest\b~s

替换:<span style="color: #FF0000;">[=14=]</span>

Pattern Demo

代码:(Demo)

$string="This is a great test! We're testing something awesome. Click here to <a href=\"whatever\">test it!</a>.";
$pattern='~(?:<[^>]*>.*?</[^>]*>(*SKIP)(*FAIL))|\btest\b~s';
$replace='<span style="color: #FF0000;">[=10=]</span>';
echo preg_replace($pattern,$replace,$string);

输出:

This is a great <span style="color: #FF0000;">test</span>! We're testing something awesome. Click here to <a href="whatever">test it!</a>.