代码之家  ›  专栏  ›  技术社区  ›  Nikit

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

  •  1
  • Nikit  · 技术社区  · 14 年前

    这些代码在$TEXT中找到第一个$WORD,并将其替换为:

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

    但如果这个词被“a”标记包围,我想忽略,例如,搜索只应在此处找到第二个“word”:

    <a href="something">text text word text</a>. text2 text2 word text2...
    
    3 回复  |  直到 14 年前
        1
  •  1
  •   Gordon Haim Evgi    14 年前

    使用A DOM 解析器查找包含指针且没有名为“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中范围内的Word。如果您也要排除这些内容,则必须将xpath调整为:

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

    查找包含不嵌套在元素内任何位置的指针的所有文本节点。

    有许多第三方解析器值得一提,目的是增强 DOM : phpQuery , Zend_Dom , QueryPath FluentDom .

        2
  •  2
  •   phimuemue    14 年前

    我认为只使用正则表达式是可能的,但是很麻烦。所以这里有一个程序化的方法,那就是,无论如何,肮脏。

    我会首先取代一切 word 由原始字符串中未出现的辅助字符串(例如 @jska_x )然后我会用正则表达式替换 JSKAYXX 里面 a -标记以恢复不想替换的单词。

    毕竟,我会取代 JSKAYXX 通过 target_word .

        3
  •  2
  •   bisko    14 年前
    @\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并检查单词是否在允许的标记中,然后替换它。