我正在将页面读入变量,我想禁用地址中不包含“remedy”一词的所有链接。到目前为止我的代码抓住了所有链接,包括“补救”。我做错了什么?
$page = preg_replace('~<a href=".*?(?!remedy).*?".*?>(.*?)</a>~i', '<font color="#808080">$1</font>', $page);
- 解决方案 -
$page = preg_replace('~<a href="(.(?!remedy))*?".*?>(.*?)</a>~i', '<font color="#808080">$2</font>', $page);
答案 0 :(得分:3)
尝试~<a href="(.(?!remedy))*?".*?>(.*?)</a>~i
对于这个问题,你做错了什么:正则表达式在任何可能的情况下匹配,并且对于每个网址(即使包含remedy
),可以匹配'~<a href=".*?(?!remedy).*?".*?>(.*?)</a>~i'
,因为你没有指定 remedy
可能未包含在属性中的任何位置,但是您指定必须有任何/不存在(.*?
)remedy
除了那些以<a href="remedy"
开头的网址外,任何网址都是如此。希望人们能理解......
答案 1 :(得分:0)
我可能会用这个:
<a href="(?:(?!remedy)[^"])*"[^>]*>([^<]*)</a>
最有趣的部分是:
"(?:(?!remedy)[^"])*"
每次[^"]
即将消耗另一个角色时,它会向前瞻产生,因此它确认它不是单词remedy
的第一个字符。使用[^"]
代替.
会阻止它查看结束引号之外的任何内容。我也冒昧地用否定的角色类替换你的.*?
。这有同样的目的,使匹配“保持”在您想要匹配的区域。它也更高效,更强大。
当然,我假设<a>
元素的内容是纯文本,其中没有更多元素嵌套。事实上,这只是我所做的许多简化假设之一。如果没有它们,您就无法将HTML与正则表达式匹配。