1

我想将列表中的单词(在文件或数据库中)更改为 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?

4

1 回答 1

2

所以我的理解是你有一个单词列表,需要在 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;
?>

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

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

类似的东西对你有用吗?

于 2010-10-11T14:26:06.597 回答