这些代码在$ 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...
答案 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")]'
查找包含针的所有文本节点,这些节点未嵌套在元素内的任何位置。
有许多值得一提的第三方解析器旨在增强DOM:phpQuery,Zend_Dom,QueryPath和FluentDom。