正则表达式,在字符串中查找单词,但不包含标记

时间:2010-08-23 06:31:18

标签: php regex

这些代码在$ text中找到第一个出现$ word,并用以下内容替换它:

<?php
  $text = preg_replace("/\b($word)\b/i", 'something', $text, 1);
?>

但我想忽略如果这个单词被“a”标签包围,例如,搜索应该只找到第二个“单词”:

<a href="something">text text word text</a>. text2 text2 word text2...

3 个答案:

答案 0 :(得分:2)

我认为只使用正则表达式就可以做到这一点,但很麻烦。所以这是一种程序化的方式,但是,这很脏。

我首先用原始字符串中没有出现的辅助字符串替换word的每个出现(例如@jska_x)。然后我会在@jska_x - 标记内对a进行正则表达式替换,以便恢复您不想替换的单词。

毕竟,我会将@jska_x替换为target_word

答案 1 :(得分:2)

@\b(word\d+)\b(?![^<>]*</|[^><]*>)@i

<a href="something">text text word1 text</a>. text2 \ (cont. on next line)
<a asdasd> text2 word2 text2... fwefw fwe few fw <a>word3</a> \
<a href="/word5.html">asdada</a>

// don't mind the numbers after word. Used them for detection which word matches

这样的事情可以解决问题,但我建议你不要在这个任务上使用正则表达式。可能你可以使用DOM并检查单词是否不在允许的标签中,然后替换它。

答案 2 :(得分:1)

使用DOM Parser查找包含针的所有文本节点,以及没有名称为“a”的父元素的文本节点:

$html = <<< HTML
<p>
    . text2 text2 word text2...
    <a href="something">text text word <span> word </span> text</a>
    . text2 text2 word text2...
<p>
HTML;

代码:

$dom = new DOMDocument;
$dom->loadHTML($html);
$xp = new DOMXPath($dom);
$nodes = $xp->query('//*[name() != "a"]/text()[contains(.,"word")]');
foreach($nodes as $node) {
    // can use a Regex in here too if you are after word boundaries
    $node->nodeValue = str_replace('word', 'something', $node->nodeValue);
}
echo $dom->saveXML($dom->documentElement);

输出:

<html><body><p>
    . text2 text2 something text2...
    <a href="something">text text word <span> something </span> text</a>
    . text2 text2 something text2...
</p><p/></body></html>

注意这将如何替换a内的span内的单词。如果您也想要排除这些,则必须将XPath调整为:

'//text()[not(ancestor::a) and contains(., "word")]'

查找包含针的所有文本节点,这些节点未嵌套在元素内的任何位置。

有许多值得一提的第三方解析器旨在增强DOMphpQueryZend_DomQueryPathFluentDom