regex preg_replace - 不要替换内部链接

时间:2013-07-05 16:36:31

标签: php regex replace preg-replace

好的,这是我的情况......我在我的vBulletin论坛上安装了词汇表附加组件。如果在论坛上找到术语,它将通过词汇表定义的链接替换术语。

这是附加组件使用的正则表达式代码:

$findotherterms[] = "#\b$glossaryname\b(?=\s|[.,?!;:]\s)#i";
$replacelinkterms[] = "<span class=\"glossarycrosslinkimage\"><a href=\"$glossarypath/glossary.php?do=viewglossary&amp;term=$glossaryid\"' onmouseover=\"glossary_ajax_showTooltip('$glossarypath/glossary_crosslinking.php?do=crosslink&term=$glossaryid',this,true);return false\" onmouseout=\"glossary_ajax_hideTooltip()\"><b>$glossaryname&nbsp;</b></a></span>";
$replacelinkterms[] = "<a href=\"glossary.php?q=$glossaryname\">$glossaryname</a>";
$glossaryterm = preg_replace($findotherterms, $replacelinkterms, $glossaryterm, $vbulletin->options['vbglossary_crosslinking_limit']);
return $glossaryterm;

问题是如果论坛帖子中有一个带有现有术语的链接,该加载项将在链接中创建一个链接......

所以,让我们说“test”是一个词汇表术语,我有这个论坛帖子:

some forum post including <a href="http://www.test.com">test</a> link

插件会将其转换为:

some forum post including <a href="http://www.<a href="glossary.php?q=test">test</a>.com"><a href="glossary.php?q=test">test</a> link

那么,如果在现有链接中找到字符串,我如何修改此代码以不替换任何内容?

1 个答案:

答案 0 :(得分:3)

描述

最好实际捕获你不想用你想要替换的好字符串替换的坏字符串,然后简单地应用一些逻辑。

在这种情况下,正则表达式将:

  • 从打开的<a ...>中找到所有锚标记以关闭</a>。因为这是正则表达式中的第一个,它将捕获锚标记内存在的所有不良test字符串。
  • 找到所有字符串test,请注意,此部分可以替换为所有词汇表术语的|分隔列表。该值将插入Capture Group 1中。

/<a\b(?=\s)(?:[^>=]|=\'[^\']*\'|="[^"]*"|=[^\'"\s]*)*"\s?>.*?<\/a>|(test)

enter image description here

然后,PHP逻辑会根据是否找到捕获组1来有选择地替换文本。

PHP示例

直播示例:http://ideone.com/jpcqSR

<强>代码

    $string = 'some forum test post including <a href="http://www.test.com">test</a> link';
    $regex = '/<a\b(?=\s) # capture the open tag
(?:[^>=]|=\'[^\']*\'|="[^"]*"|=[^\'"\s]*)*"\s?> # get the entire tag
.*?<\/a>
|
(test)/imsx';

    $output = preg_replace_callback(
        $regex,
        function ($matches) {
            if (array_key_exists (1, $matches)) {
                return '<a href="glossary.php?q=' . $matches[1] . '">' . $matches[1] . '<\/a>';
            }
            return $matches[0];
        },
        $string
    );
    echo $output;

替换前

some forum test post including <a href="http://www.test.com">test</a> link

替换后

some forum <a href="glossary.php?q=test">test<\/a> post including <a href="http://www.test.com">test</a> link