PHP preg_replace - 在h1标记内不匹配

时间:2010-03-29 00:42:01

标签: php preg-replace

如果在长HTML字符串中找到关键字,我使用preg_replace来添加关键字的链接。如果在h1标签或强标签中找到关键字,我不想添加链接。

以下正则表达式几乎可以工作,基本上说(我认为):如果关键字没有立即被h1标签或强标签包裹,那么请替换为匹配的关键字,作为谷歌的粗体链接。

$result = preg_replace('%(?!<h1>)(?!<strong>)\b(bobs widgets)\b(?!<\/strong>)(?!<\/h1>)%i','<a href="http://www.google.com"><strong>$1</strong></a>', $result, -1);

(如果在强标签中我不想匹配的原因是因为我通过大量关键字递归,所以不希望在后续传递中链接已经链接的关键字)

以上工作正常并且不匹配:

<h1>bobs widgets</h1>

但它会匹配以下文本中的关键字,因为h1标记不是关键字的任何一侧:

<h1>Here are bobs widgets for sale</h1>

我需要将空格任意一边并尝试添加\ s *但这并不能让我随处可见。我非常感谢在这里推动正确的方向。

2 个答案:

答案 0 :(得分:1)

正则表达式是这项工作的错误工具。这已在Stack Overflow上多次讨论过(例如网站上的most famous thread)。

您需要的是HTML解析器,例如Simple HTML DOM Parser。帮自己一个忙,从一开始就使用这样的东西。想象一下,如果遇到有人添加了属性的<h1>,或者有人不正确地关闭了标记,那么会发生什么事情,所以你在</strong>和{{1}上有一个混合顺序}}。使用正则表达式来处理这样的事情是不值得的,有时甚至是不可能的。

答案 1 :(得分:1)

...请记住,最终这种方法会导致悲伤,你需要开始寻找更好的方法。一种方法是使用'tidy'将你的html修复为可解析的xml,然后php提供一些xml操作API来处理数据。

无论如何,这是一个答案。

您可以添加一些通配符而不是单词边界。这样的事情可以解决问题:

([^<>]*)(bobs widgets)([^<>]*)

然后,添加一些替换标记以将文本的其余部分保留在输出中:

'$1<a href="http://www.google.com"><strong>$2</strong></a>$3'

现在点击保存并隐藏在沙发后面;)