php正则表达式匹配html标签之外

时间:2011-10-25 15:33:17

标签: php regex preg-replace pcre

我在html页面上创建了一个preg_replace。我的模式旨在为html中的某些单词添加周围标记。但是,有时我的正则表达式会修改html标记。例如,当我尝试替换此文本时:

<a href="example.com" alt="yasar home page">yasar</a>

因此yasar读取<span class="selected-word">yasar</span>,我的正则表达式也会替换锚标记的alt属性中的yasar。我正在使用的当前preg_replace()看起来像这样:

preg_replace("/(asf|gfd|oyws)/", '<span class=something>${1}</span>',$target);

如何制作正则表达式,使其与html标签内的任何内容都不匹配?

4 个答案:

答案 0 :(得分:20)

您可以使用断言,因为您必须确保搜索的单词出现在>后或任何<之前。后一个测试更容易实现,因为前瞻断言可以是可变长度:

/(asf|foo|barr)(?=[^>]*(<|$))/

另请参阅http://www.regular-expressions.info/lookaround.html以获得该断言语法的一个很好的解释。

答案 1 :(得分:7)

Yasar,复活这个问题,因为它有另一个未被提及的解决方案。

此解决方案不会仅检查下一个标记字符是否为开始标记,而是会跳过所有<full tags>

关于使用正则表达式解析html的所有免责声明,这里是正则表达式:

<[^>]*>(*SKIP)(*F)|word1|word2|word3

这是demo。在代码中,它看起来像这样:

$target = "word1 <a skip this word2 >word2 again</a> word3";
$regex = "~<[^>]*>(*SKIP)(*F)|word1|word2|word3~";
$repl= '<span class="">\0</span>';
$new=preg_replace($regex,$repl,$target);
echo htmlentities($new);

以下是此代码的online demo

参考

  1. How to match pattern except in situations s1, s2, s3
  2. How to match a pattern unless...

答案 2 :(得分:0)

这可能是你想要的事情:http://snipplr.com/view/3618/ 一般来说,我建议不要这样做。更好的选择是去除所有HTML标记,而是依赖BBcode,例如:

[b]bold text[b] [i]italic text[i]

但是我很欣赏这可能不适合您正在尝试做的事情。

另一个选项可能是HTML Purifier,请参阅:http://htmlpurifier.org/

答案 3 :(得分:0)

最重要的是,这应该有效:

echo preg_replace("/<(.*)>(.*)<\/(.*)>/i","<$1><span class=\"some-class\">$2</span></$3>",$target);

但是,我不知道这会有多安全。我只是提出了一种可能性:)