簡體   English   中英

正則表達式,在字符串中查找單詞,但不被標簽包圍

[英]Regular expression, find word in string, but not surrounded by tag

這些代碼在$ 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...

我認為僅使用正則表達式即可做到這一點,但麻煩。 所以這是一種編程方式,但是很臟。

我將首先用原始字符串中沒有出現的輔助字符串(例如@jska_x )替換word的每次出現。 然后,我會做一個正則表達式替換@jska_xa以恢復你不想更換的話-標簽。

畢竟,我會用@jska_x替換target_word

@\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並檢查在允許的標簽中是否沒有word,然后將其替換。

使用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范圍內的單詞。 如果您也想排除這些,則必須將XPath調整為:

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

查找所有未嵌套在元素內任何位置的包含針的文本節點。

有很多值得一提的旨在增強DOM的第三方解析器: phpQueryZend_DomQueryPathFluentDom

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM