在内容片段内第一次出现关键字时包装粗体/强标签?

时间:2011-01-30 14:27:26

标签: php regex preg-replace domdocument

我正在寻找最简单的方法来围绕预定义关键字词组的第一次出现包装粗体标签,当该词组没有出现在标题标签中或作为html属性值时。找到第一个匹配后,退出例程。

例如,如果关键字是“蓝色小部件”,则内容为:

blue widgets and accessories for blue widgets can be found here

然后在例程过滤内容后,它将返回:

<b>blue widgets</b> and accessories for blue widgets can be found here

但是,如果第一次出现的单词“blue widgets”在属性或标题标签中,它将跳过这些并转到下一个。例如,

<img src="foo.png" title="A site about blue widgets" alt="blue-widget" />
<h2>This is a site about blue widgets</h2>
<p>We've got lots of blue widgets and blue widget accessories...

在上面的内容中,只有句子“我们有很多蓝色小部件和蓝色小部件配件”的关键字的外观才会加粗。

有人能举例说明如何做到这一点吗?

1 个答案:

答案 0 :(得分:1)

如果你还在考虑使用正则表达式,请查看:

$source = <<<EOS
<img src="foo.png" title="A site about blue widgets" alt="blue-widget" />
<h2>This is a site about blue widgets</h2>
<p>We've got lots of blue widgets and blue widget accessories...';
EOS;

$term = 'blue widgets';

// convert search term to valid regex
$term0 = preg_replace(array('~\A\b~', '~\b\z~', '~\s+~'), 
                      array('\b', '\b', '\s+'),
                      preg_quote(trim($term), '~'));

$regex = <<<EOR
~\A   # anchoring at string start ensures only one match can occur
(?>
   <(h[1-6])[^>]*>.*?</\\1>   # a complete h<n> element
 | </?\w+[^>]*+>              # any other tag
 | (?:(?!<|{$term0}).)*+      # anything else, but stop before '<' or the search term
)*+
\K    # pretend the match really started here; only the next part gets replaced
{$term0}
~isx
EOR;

echo preg_replace($regex, "<strong>$0</strong>", $source);

<强> run it on ideone.com

我甚至不确定可能使用正则表达式执行此操作,这就是为什么我遇到了解决问题的麻烦。像这个解决方案一样丑陋,它就像我能做到的一样简单。要做到这一点,我必须忽略许多可能破坏它的因素 - 例如CDATA部分,SGML注释,<script>元素和属性值中的尖括号等等。这只是在有效 HTML。

有趣的是,我希望它能说服你一劳永逸地忘记正则表达式并使用专用工具,正如其他响应者所建议的那样。