我有一个文本($text
)和一个单词数组($tags
)。文本中的这些单词应该替换为指向其他页面的链接,这样它们就不会破坏文本中的现有链接。在CakePHP中,TextHelper中有一个方法可以执行此操作,但它已损坏,并且会破坏文本中现有的HTML链接。该方法假设像这样工作:
$text=Text->highlight($text,$tags,'<a href="/tags/\1">\1</a>',1);
下面是CakePHP TextHelper中的现有代码:
function highlight($text, $phrase, $highlighter = '<span class="highlight">\1</span>', $considerHtml = false) {
if (empty($phrase)) {
return $text;
}
if (is_array($phrase)) {
$replace = array();
$with = array();
foreach ($phrase as $key => $value) {
$key = $value;
$value = $highlighter;
$key = '(' . $key . ')';
if ($considerHtml) {
$key = '(?![^<]+>)' . $key . '(?![^<]+>)';
}
$replace[] = '|' . $key . '|ix';
$with[] = empty($value) ? $highlighter : $value;
}
return preg_replace($replace, $with, $text);
} else {
$phrase = '(' . $phrase . ')';
if ($considerHtml) {
$phrase = '(?![^<]+>)' . $phrase . '(?![^<]+>)';
}
return preg_replace('|'.$phrase.'|i', $highlighter, $text);
}
}
答案 0 :(得分:2)
您可以在此处查看(并运行)此算法:
http://www.exorithm.com/algorithm/view/highlight
通过一些变化可以使它变得更好更简单,但它仍然不完美。虽然效率较低,但我推荐Ben Doom的解决方案之一。
答案 1 :(得分:1)
替换HTML中的文本与替换纯文本根本不同。要确定文本是否是HTML标记的一部分,您需要查找所有标记以便不考虑它们。正则表达式并不是真正的工具。
我会尝试以下解决方案之一:
我认为第一个可能更有效率,但更容易出现程序员错误,所以我会留给你。
如果您想知道我为什么不直接解决此问题,请查看网站上有关正则表达式和HTML的所有问题,以及正则表达式不是解析器的方法。
答案 2 :(得分:0)
这段代码很好用。您可能需要做的是检查<span class="highlight">
的CSS,并确保它设置为某种颜色,以便您区分它是高亮的。
.highlight { background-color: #FFE900; }
答案 3 :(得分:0)
非晶 - 我注意到格特编辑了你的帖子。您发布的两个代码片段是否完全?
所以尽管原始代码是为突出显示而设计的,但我知道你正试图将其重新用于生成链接 - 它应该,并且确实可以正常工作(测试为已发布)。
HOWEVER 在第一个代码片段中转义可能是一个问题。
$text=Text->highlight($text,$tags,'<a href="/tags/\1">\1</a>',1);
工作得很好......但是如果你使用说话标记而不是引号,则反斜杠会作为逃避标记消失 - 你需要逃避它们。如果你不这样做,你会得到%01链接。
说明标记的正确方法是:
$text=Text->highlight($text,$tags,"<a href=\"/tags/\\1\">\\1</a>",1);
(注意使用\ 1而不是\ 1)