【问题标题】:Howto change some words into links in HTML?如何将某些单词更改为 HTML 中的链接?
【发布时间】:2010-10-11 11:30:32
【问题描述】:

我想将列表中的单词(在文件或数据库中)更改为 HTML 网站中的链接。我使用了 str_replace,但我无法替换已经在链接中的单词。

例如。我有这样的html:

Lorem ipsum donor et simet <a>lorem ipsum</a> eta raoa talkesa z uta.

我想将所有“ipsum”替换为链接,但在 [a]lorem ipsum[a] 中跳过 ipsum。 我不知道,maby preg_replace?

【问题讨论】:

    标签: php preg-replace str-replace


    【解决方案1】:

    所以我的理解是你有一个单词列表,需要在 HTML 正文中链接。 str_replace() 处理它,但不适用于锚点内的链接?

    如果匹配词在锚标签内,您希望忽略它们?

    PHP 不支持可变宽度的负向回溯,因此在匹配单词之前有锚标记的地方很难说不匹配,因为头部锚标记是可变长度的。

    我处理此类问题的方式是全部替换,然后撤消不应该进行的更改。

    <?php
    // Setup data
    $words = array('lorem' => 'www.google.com',
                   'ipsum' => 'www.bbc.co.uk',
                   'test' => 'www.amazon.co.uk');
    
    $textBody = '<p>This is a short test of <a href="www.slashdot.org">lorem ipsum</a> automatic anchoring.  Let us see if it works, any incidences of lorem or ipsum, should be caught.</p>';
    
    // Make basic replacements, but use a different tag than anchor
    // so it can be detected separately from previously existing anchors
    // I am using the <argh> tag
    
    $wordExpressions = array();
    $wordReplacements = array();
    foreach ($words as $cWord => $cLink) {
      $wordExpressions[] = '#' . preg_quote($cWord) . '#';
      $wordReplacements[] = '<argh href="' . $cLink . '">' . $cWord . '</argh>';
    }
    
    $replacedText = preg_replace($wordExpressions, $wordReplacements, $textBody);
    
    // At the moment, there are nested anchors
    echo $replacedText;
    
    // Use a fairly horrific recursive anchor tag callback replacement to delete any
    // <argh> tags inside <a> tags
    $replacedText =
      preg_replace_callback("#(<a [^>]*>)((?:[^<]|<(?!/?a>)|(?R))+)(</a>)#",
                            create_function('$a', 'return $a[1] . preg_replace("#<argh[^>]*>(.*?)</argh>#", "$1", $a[2]) . $a[3];'),
                            $replacedText);
    
    // No nested anchors now
    echo $replacedText;
    
    // Finally replace the <argh> tags with straight <a>s
    $replacedText = preg_replace(array('#<argh #', '#</argh>#'), array('<a ', '</a>'), $replacedText);
    
    // The output should now be correct
    echo $replacedText;
    ?>
    

    这看起来有点糟糕,尤其是递归正则表达式回调。所做的只是匹配成对的锚标签并将匹配传递给一个函数,该函数简单地返回修补的对并从内部内容中去除新标签。在"Mastering Regular Expressions" by Jeffery Friedl 中有一个很好的关于递归替换的讨论。

    标签可以是任何东西,我使用了这个词,因为它不太可能存在于 HTML 中并且似乎适合手头的问题。 :-)

    这样的事情对你有用吗?

    【讨论】:

    • 你非常了解我:)。您的解决方案似乎有效,但我需要对各种内容进行一些测试。非常感谢!
    猜你喜欢
    • 2016-05-18
    • 1970-01-01
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-29
    • 1970-01-01
    相关资源
    最近更新 更多