【问题标题】:regex preg_replace - don't replace inside links正则表达式 preg_replace - 不要替换内部链接
【发布时间】:2013-07-03 19:45:58
【问题描述】:

好的,这是我的情况...我在我的 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;

问题是,如果论坛帖子中有一个包含现有术语的链接,插件将在链接内创建一个链接...

假设“测试”是一个词汇表,我有这个论坛帖子:

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

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

【问题讨论】:

标签: php regex replace preg-replace


【解决方案1】:

说明

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

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

  • 找到从打开&lt;a ...&gt;到关闭&lt;/a&gt;的所有锚标签。因为这是正则表达式中的第一个,它将捕获存在于锚标记内的所有不需要的 test 字符串。
  • 找到所有字符串test,注意这部分可以替换为您所有词汇表术语的| 分隔列表。该值被插入到捕获组 1。

/&lt;a\b(?=\s)(?:[^&gt;=]|=\'[^\']*\'|="[^"]*"|=[^\'"\s]*)*"\s?&gt;.*?&lt;\/a&gt;|(test)

然后 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 &lt;a href="http://www.test.com"&gt;test&lt;/a&gt; link

更换后

some forum &lt;a href="glossary.php?q=test"&gt;test&lt;\/a&gt; post including &lt;a href="http://www.test.com"&gt;test&lt;/a&gt; link

【讨论】:

    猜你喜欢
    • 2017-11-12
    • 1970-01-01
    • 1970-01-01
    • 2020-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多