我正在创建一个自动完成,我有一个小问题的结果突出显示。你看,我的搜索算法非常慷慨,忽略了结果中的撇号,因此像joes
这样的查询将匹配Joe's
。搜索算法已经完成,现在是高亮部分。我想把匹配的图案加粗。
假设我有一个原始的未格式化的结果:Joe’s
(请注意rsquo u2019),我想这样突出显示它:Joe’s
,对于以下查询joes
, joe's
和joe’s
(rsquo u2019)
我在查询中包含了右边的单引号,因为你不知道是否有人从word文档或其他东西中复制了查询。
我可以很容易地通过忽略引号在搜索/结果字符串中都存在的事实来做到这一点,但是当您不小心键入像joes'
或更糟糕的jo'es
这样的东西时,这会弄乱整个搜索点。所以我需要保留引号位置。还请注意,撇号也可以出现在未格式化的结果字符串中的任何位置,如Suq'Ata
。
下面是一个场景列表:
- String:
Liliana's
查询: - Result:
Liliana's
lilianas
, liliana's
- String:
Suq'Ata
查询: - Result:
Suq'Ata
suqat
, suq'at
- String:
Telim'Tor's
查询: - Result:
Telim'Tor's
telimt
, telim't
应该注意的是,查询中引号的位置很重要,而当你在查询中放错引号时,它应该根本不匹配。因此,要么你有正确的引号位置,要么根本没有引号来突出显示原始字符串。
我实际上并不介意是否建议的解决方案是将每个字母分开并循环它(已经考虑过了),因为我将在给定的时间内最多处理5个字符串。我期待你的建议!
来自提问者的更新问题规格:
- 如果用户的查询有引号,它的位置必须匹配原始字符串的引号。如。查询"Joe’s"不匹配原始字符串"Joe’s"。
- 我们只需要将查询的开头与原始字符串的开头进行匹配。
我可以想到更好的算法,但首先,这里是一个快速而肮脏的第一次尝试,使用每个字母的朴素循环方法:
var quotesRegex = /['u2019]/g;
function highlightMatch(origStr, query) {
query = query.toLowerCase();
var j = 0;
for (var i = 0; i < query.length; ++i, ++j) {
// Query has a quote; it needs to be in the same position as origStr
if (query.charAt(i).match(quotesRegex)) {
if (!origStr.charAt(j).match(quotesRegex)) {
return origStr; // quote position mismatch
}
continue;
}
while (origStr.charAt(j).match(quotesRegex)) {
j++;
}
if (origStr.charAt(j).toLowerCase() != query.charAt(i)) {
return origStr;
}
}
return "<b>" + origStr.slice(0, j) + "</b>" + origStr.slice(j);
}
JSFiddle: http://jsfiddle.net/FFt2T/6/