正则表达式匹配字符串中的单词或短语但如果网址的一部分或<a> </a>标记内部不匹配.(PHP)

Joe*_* D. 2 html php regex preg-replace

我知道正则表达式不适合与HTML字符串一起使用,我已经看过PHP Simple HTML DOM Parser,但仍然相信这是要走的路.所有HTML标签都将由我的论坛软件生成,因此它们将是一致且有效的HTML.

我想要做的是制作一个插件,它将在HTML字符串中找到一个关键字(或短语)列表,并用我指定的链接替换它们.例如,如果有人输入:

I use Amazon for that.
Run Code Online (Sandbox Code Playgroud)

它将取代它:

I use <a href="http://www.amazon.com">Amazon</a> for that.
Run Code Online (Sandbox Code Playgroud)

问题当然是如果"亚马逊"在URL中,它也会被替换.我用这个网站上的回调函数解决了这个问题,略有修改.

但是现在我还有一个问题,它仍然取代了开始和结束标签之间的单词.

<a href="http://www.amazon.com">My Amazon Link</a>
Run Code Online (Sandbox Code Playgroud)

它将匹配"我的亚马逊链接"中的"亚马逊"

我真正需要的是匹配说"亚马逊"的正则表达式,除了<a href和之间</a>

有任何想法吗?

Tim*_*ker 9

使用DOM肯定是更可取的.

但是,你可能会逃避这个:

$result = preg_replace('%Amazon(?![^<]*</a>)%i', '<a href="http://www.amazon.com">Amazon</a>', $subject);
Run Code Online (Sandbox Code Playgroud)

它匹配Amazon只有当

  1. 它后面没有结束</a>标记,
  2. 它本身不是标签的一部分,
  3. 没有插入标记,即如果标记可以嵌套在<a>标记内,它将被抛弃.

因此它会改变这个:

I use Amazon for that.
I use <a href="http://www.amazon.com">Amazon</a> for that.
<a href="http://www.amazon.com">My Amazon Link</a>
It will match the "Amazon" in "My Amazon Link"
Run Code Online (Sandbox Code Playgroud)

进入这个:

I use <a href="http://www.amazon.com">Amazon</a> for that.
I use <a href="http://www.amazon.com">Amazon</a> for that.
<a href="http://www.amazon.com">My Amazon Link</a>
It will match the "<a href="http://www.amazon.com">Amazon</a>" in "My <a href="http://www.amazon.com">Amazon</a> Link"
Run Code Online (Sandbox Code Playgroud)


lon*_*day 6

不要这样做.无论您的HTML多么一致,您都无法使用Regex可靠地执行此操作.

但是这样的事情应该有效:

<?php
$dom = new DOMDocument;
$dom->load('test.xml');
$x = new DOMXPath($dom);

$nodes = $x->query("//text()[contains(., 'Amazon')][not(ancestor::a)]");

foreach ($nodes as $node) {
    while (false !== strpos($node->nodeValue, 'Amazon')) {
        $word = $node->splitText(strpos($node->nodeValue, 'Amazon'));
        $after = $word->splitText(6);

        $link = $dom->createElement('a');
        $link->setAttribute('href', 'http://www.amazon.com');

        $word->parentNode->replaceChild($link, $word);
        $link->appendChild($word);

        $node = $after;
    }
}

$html = $dom->saveHTML();
echo $html;
Run Code Online (Sandbox Code Playgroud)

它很冗长,但实际上会有效.