【发布时间】:2013-05-07 14:55:01
【问题描述】:
场景
我正在尝试开发一个 Javascript 文本高亮功能。 它在输入中接收要搜索的文本、要搜索的标记数组、用于包装找到的匹配项的类:
var fmk = fmk || {};
fmk.highlight = function (target, tokens, cls) {
var token, re;
if (tokens.length > 0) {
token = tokens.pop();
re = new RegExp(token, "gi");
return this.highlight(
target.replace(re, function (matched) {
return "<span class=\"" + cls + "\">" + matched + "</span>";
}), tokens, cls);
}
else { return target; }
};
它基于递归替换,将<span> 标签包裹在找到的匹配项周围。
问题
如果有两个记号,而后者是前一个的子串那么只有后一个记号会被高亮。在 jsFiddle 示例中,尝试以下标记:'ab b'。
如果标记包含包装序列的子字符串(即
<span class="[className]"></span>)和另一个匹配标记,则高亮失败并返回脏结果。在 jsFiddle 示例中尝试这些标记:'red ab'。
注意在实际应用中允许单字符令牌。
问题
如何避免这些错误?我想出了这些方法:
预处理标记,删除作为其他子字符串的标记。缺点:在n个token的情况下需要在预处理阶段搜索O(n^2);好的匹配被切断了。
在应用包装器之前预处理匹配,以便仅切断 子字符串 匹配。缺点:同样需要进一步的计算。无论如何,我不知道从哪里开始在替换回调函数中实现这个。
【问题讨论】:
-
这并不像您正在做的那么简单,您已经证明了这一点。我不认为 jQuery 是解决这个问题的途径。您需要获取一个元素,递归搜索其后代节点,并为任何文本节点,将其替换为新的跨度节点
-
你认为为什么需要使用 jQuery?这对某些事情很好,但我不会说这是一个。我的意思是,您可以使用 jQuery 最初选择要在其中突出显示的元素,但我不会使用 jQuery 进行实际操作
-
@Ian。我认为在这种情况下不需要 jQuery。我的意思是,该算法根本不使用 jQuey,我什至没有在问题的标签列表中添加 jQuery。这是一个纯 Javascript 解决方案。虽然我最终使用 jQuery 与 DOM 交互。
-
啊,好吧,我只是很困惑为什么你问“我在哪里使用 jQuery”(或者任何问题)。我发誓我最近回答了一个类似的问题,所以让我看看能不能找到我的答案
-
我刚刚发布了一个答案。我意识到,当我之前尝试做这样的事情时,当我去发布答案时,已经有人想出来了,所以我放弃了,因为我无法让它发挥作用。所以我自己来创造这一切,因为这种操纵引起了我的兴趣,而且我对自己的所作所为有点过火了。尽管如此,我想用它制作一个迷你库并维护它,在任何地方进行改进并尽可能添加,所以这就是我开发它的原因。希望对您有所帮助,如果您有任何问题,请告诉我
标签: javascript algorithm substring highlight