正则表达式用于转义字符突出显示

时间:2016-08-13 21:57:26

标签: javascript regex

我正在使用JavaScript构建自动完成功能,需要在搜索时突出显示单词:

Gist

工作正常,但转义字符存在问题。 尝试突出显示包含转义字符的文本时(例如regex &>< example),会发生以下情况:

Service Worker Typings to Supplement lib.webworker.d.ts

这种情况正在发生,因为我正在做以下事情:

element.innerHTML.replace(/a/g, highlight)

function highlight(str) {
  return '<span class="foo"' + '>' + str + '</span>';
}

innerHTML包含单词&amp;,因此有意义。

总之,我需要一种解决方法,所以我想要一个功能:

  • 收到aregex <br> example并返回regex &lt;br&gt; ex<span class="foo">a</span>mple
  • 收到rregex <br> example并返回<span class="foo">r</span>egex &lt;b<span class="foo">r</span>&gt; example
  • 收到<regex <br> example并返回regex <span class="foo">&lt;</span>br&gt; example

条目可能包含也可能不包含html块,请参阅问题highlighting example(搜索<br>&

1 个答案:

答案 0 :(得分:1)

str.replace仅返回带有预期替换的新字符串。原始字符串不变。

var str = 'replace me';
var str2 = str.replace(/e/g, 'E');

// For display only
document.write('<pre>' + JSON.stringify({
  str: str,
  str2: str2
}, null, 2) + '</pre>');

因此,代码需要将返回值从替换设置回所需的元素。

此外,innerHTML将返回转义文本而非未转义文本。这可以在函数内部转义,但如果你可以使用textContent,为什么还要麻烦。但是,在将高亮显示的文本设置为元素时使用innerHTML,它将为我们自动转义文本。 :)

UPDATE :将值传递给函数,然后设置为元素:

注意:

  • regexp可能会更加健壮,以避免使用lastIndex
  • 来处理特殊情况
  • 需要对输入进行一些保护,因为有人可能会提供令人讨厌的正则表达式模式。此示例中有一个最小的保护检查。

higlightElemById('a', 'regex &>< example', 'a');
higlightElemById('b', 'regex &>< example', '&');
higlightElemById('c', 'regex <br> example', '<');
higlightElemById('d', 'regex <br> example', 'e');
higlightElemById('e', 'regex <br> example', '[aex]');

function higlightElemById(id, str, match) {
  var itemElem = document.getElementById(id);
  // minimal regexp escape to prevent shenanigans
  var safeMatch = match.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  // construct regexp to match highlight text
  var regexp = new RegExp('(.*?)(' + safeMatch + ')', 'g');
  var text = '';
  var lastIndex;
  var matches;
  
  while (matches = regexp.exec(str)) {
    // Escape the non-matching prefix
    text += escapeHTML(matches[1]);
    // Highlight the match
    text += highlight(matches[2]);
    // Cache the lastIndex in case no regexp at end
    lastIndex = regexp.lastIndex;
  }

  if (text) {
    text += escapeHTML(str.substr(lastIndex));
  } else {
    text += escapeHTML(str);
  }

  itemElem.innerHTML = text;
}

function highlight(str) {
  return '<span class="myHighlightClass">' + str + '</span>';
}

function escapeHTML(html) {
  this.el = this.el || document.createElement('textarea');

  this.el.textContent = html;
  return this.el.innerHTML;
}
.myHighlightClass {
  text-decoration: underline;
  color: red;
}
<div id="a"></div>
<div id="b"></div>
<div id="c"></div>
<div id="d"></div>
<div id="e"></div>