高亮显示字符串中的文本

时间:2019-06-14 20:57:44

标签: javascript string algorithm

我有一种算法,可以根据查询来计算要突出显示在文本中的字符。

例如,如果我将算法文本“ 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;
};

有没有更好的方法来解决问题?

另一个例子:

  • 文本:“荷兰北荷兰省阿姆斯特丹”
  • 查询:“ amst”
  • 匹配项:[0, 4]

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)

考虑使用mark.js

替换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>');

}