Php正则表达式,用于更改位于锚外部的单词,而不是锚内部的单词


Php Regular expression for change the word that is outside the anchor, not inside the anchor

下面有一个正则表达式'reg_replace('/(abc)(?!([^''"]''">[^<])<a> )/','$1',$content)'我想如果abc在锚定标记内,那么它不会被替换,但如果它在锚定标签外,那么它必须被替换E.g<a href="any@domain.com" title="adada" target="sdada">he is abc guy</a> is an abc guy etc...在这种情况下,锚点标签内的abc不会被替换,但标签外的abc须被替换

您可以使用它来避免链接、脚本、样式、注释、cdata和标签属性中的内容:

$regex = '~(?:<(a|script|style)'b.*?</'1>|<!--.*?-->|<!'[CDATA'[.*?]]>|<.*?>)'
       . '(*SKIP)(*FAIL)|abc~si';
$result = preg_replace($regex, 'HiHa!!', $content);

当子字符串与(*SKIP)回溯控制谓词之前的子模式匹配,并且如果子模式在(*SKIP)之后失败,正则表达式引擎不会尝试将子字符串与模式的另一部分(此处的另一个部分是abc)匹配,而是在子字符串之后继续。(*FAIL)强制子模式失败。

s修饰符允许点与换行符匹配。

模式可以优化为:

$regex = '~(?><(a|script|style)'b(?>[^<]++|<(?!/'1>))*+</'1>|'
       . '<!--(?>[^-]++|-(?!->))*+-->|'
       . '<!'[CDATA'[(?>[^]]++|](?!]>))*+]]>|<[^>]*+>)++(*SKIP)(*FAIL)|abc~si';

更合适的方法

由于您正在尝试修改html文档,因此可以使用DOMDocument和XPath,它们是为这类任务设计的工具:

$doc = new DOMDocument();
@$doc->loadHTML($content);
$xpath = new DOMXPath($doc);
$textnodes = $xpath->query('//text()[not(ancestor::a)]');
foreach ($textnodes as $textnode) {
    $textnode->nodeValue = str_replace('abc', 'HiHa!!', $textnode->nodeValue);
}
$result = $doc->saveHTML();
print_r($result);