我有一个任务,根据查询来计算要突出显示在文本中的字符。
假设给定的文本为"London, United Kingdom"
,查询为"lond"
。然后结果应该是[[0, 4]]
。
我有一个简单的实现,可以很好地解决这种情况:
// ...
.reduce((result, word) => {
const wordLen = word.length;
const prefix = wordCharacterRegex.test(word[0]) ? "\\b" : "";
const regex = new RegExp(prefix + escapeRegexCharacters(word), "i");
const index = text.search(regex);
if (index > -1) {
result.push([index, index + wordLen]);
text =
text.slice(0, index) +
new Array(wordLen + 1).join(" ") +
text.slice(index + wordLen);
}
return result;
}, [])
// ...
,但是如果文本为"EC2V 6DB, London, United Kingdom"
并且查询为"ec2v6db"
,则该文本将不起作用,因为正则表达式将为/\bec2v6db/i
。
那么,如何更改我的代码并解决问题?
答案 0 :(得分:1)
首先,如果第一个字符是单词char,则添加的单词边界应该与非单词char保持一致:如果在单词char之前添加\b
,请添加\B
在非单词字符之前获得相同的行为。
const prefix = wordCharacterRegex.test(word[0]) ? "\\b" : "\\B";
然后,尚不清楚escapeRegexCharacters
方法的外观,但可以在其中将\s*
插入关键字的每个字符之间。
function escapeRegexCharacters(s) {
var res = s.replace(/([-\/\\^$*+?.()|[\]{}])|[\s\S]/g, (m,g) => (g ? "\\" + g : m) + "\\s*");
return res.substring(0, res.length -3);
}
这是一个演示:
let word = "ec2v6db"; // lond is checked
let text = "EC2V 6DB, London, United Kingdom";
const wordCharacterRegex = /\w/;
function escapeRegexCharacters(s) {
var res = s.replace(/([-\/\\^$*+?.()|[\]{}])|[\s\S]/g, (m,g) => (g ? "\\" + g : m) + "\\s*");
return res.substring(0, res.length -3);
}
const prefix = wordCharacterRegex.test(word[0]) ? "\\b" : "\\B";
const regex = new RegExp(prefix + escapeRegexCharacters(word), "i");
// Replacing text with spaces
console.log(text.replace(regex, m => " ".repeat(m.length)));
// => " , London, United Kingdom"
// Adding tags around the match
console.log(text.replace(regex, "<highlight>$&</highlight>"));
// Getting the indices:
let match = regex.exec(text);
if (match) {
console.log([match.index, match.index+match[0].length]);
}