2016-08-13 56 views
1

我建立在JavaScript中自动完成,需要强调的话做一个搜索时:正则表达式的转义字符突出

highlighting example

这工作正常,但有一个与转义字符的问题。 当试图突出与转义字符的文本(例如regex &>< example),下面是发生的事情:

regex highlighting

这是怎么回事,因为我做了以下内容:

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块,看问题here(搜索<br>&

+2

如果你不想实体退换,使用'textContent'获取内容,而'innerHTML'与跨度包括设置呢? – adeneo

+0

'textContent'具有字符转义(即:'&'),它的正好不包括html,比如'span's,所以不起作用 – lante

+0

这看起来像是另一个例子'你不能用常规表达式的情景:http://stackoverflow.com/a/1732454/25216 –

回答

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:值传递给函数,然后设置为元素:

注:

  • 的正则表达式也许可以做一点更稳健避免必须处理使用的特殊情况lastIndex
  • 需要对输入进行某种保护,因为某人c应该提供一个令人讨厌的正则表达式模式。在这个例子中有一个最小保护检查。

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>

+0

感谢您的答案,但我看到一个额外的案件不包括在内: https ://jsfiddle.net/gemxuc3e/ 我更新了问题以澄清 – lante

+0

@lante在这种情况下,您所需的输出是什么?将“
”转义或不在输入中,它是否需要在输出元素中转义? –

+0

查看[这里](https://jsfiddle.net/8rd8mbm9/2/)例子中,条目可能包含也可能不包含html块(我不能禁止用户把html块作为条目)搜索'br '或'&' – lante