我有一种算法,可以根据查询来计算要突出显示在文本中的字符。
例如,如果我将算法文本“ 1000,Brussels,Belgium”传递给
查询“ 1000 bruss”,它将返回我[[0, 4], [6, 11]]
。但是现在,我需要编写一种算法,该算法将使用<strong></strong>
包装字符,因此结果应为<strong>1000</strong>, <strong>Bruss</strong>els, Belgium
。
我写了算法,但是我觉得它可能会更好,或者可能会更优雅地解决。
const highlight = (content, query, matches) => {
if (!query) {
return content;
}
const openTag = "<strong>";
const closeTag = "</strong>";
let result = content;
let shift = 0;
matches.forEach(([startIndex, endIndex]) => {
const s =
openTag +
result.slice(startIndex + shift, endIndex + shift) +
closeTag +
result.slice(endIndex + shift);
if (shift) {
result = result.slice(0, startIndex + shift) + s;
} else {
result = s;
}
shift += openTag.length + closeTag.length;
});
return result;
};
有没有更好的方法来解决问题?
另一个例子:
[0, 4]
答案 0 :(得分:2)
您可以按升序对比赛进行排序,然后只需将行进之间的部分合并在一起即可:
const highlight = (content, matches) => {
matches.sort(([a], [b]) => a - b);
let result = "";
let prevEnd = 0;
for(const [start, end] of matches) {
result += content.slice(prevEnd, start);
result += "<strong>";
result += content.slice(start, end);
result += "</strong>";
prevEnd = end;
}
result += content.slice(prevEnd);
return result;
}
(这假定匹配项不重叠,就像OPs代码一样)
或者,您也可以将替换项留给正则表达式引擎:
const result = content.replace(new RegExp(query.split(" ").join("|"), "g"), it => `<strong>${it}</strong>`);
答案 1 :(得分:2)
替换DOM中的节点可能很棘手,并且在元素移动和触发事件时会导致意想不到的后果。尽管它添加了第三方依赖性,但它具有非常干净的API,并且抽象了逻辑,因此您不必拥有它。
var instance = new Mark(".mark-context");
instance.mark("100 bruss");
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js"></script>
<p class="mark-context">
1000, Brussels, Belgium
</p>
答案 2 :(得分:1)
另一种选择是将字符串拆分为字符:
var text = '1000, Brussels, Belgium', query = [[0, 4], [6, 11]], chars = [...text];
query.forEach(([from, to]) => { chars[from] = '<strong>' + chars[from];
chars[to] = '</strong>' + chars[to] });
document.body.innerHTML = chars.join('')
console.log( chars )
答案 3 :(得分:0)
您可以使用正则表达式(RegEx)的功能来执行此操作!请参阅下面的以下功能,只需将string
设置为要搜索的文本,并将search
设置为要查找的文本。在您的情况下,string
将为“ 1000,比利时布鲁塞尔”,而search
将为“ 1000 bruss”
function highlightString(string, search){
var regEx = new RegExp(search, 'g');
return str.replace(regEx, '<strong>'+search+'</strong>');
}