在JavaScript字符串中给出关键字时,我需要强调不区分大小写.
例如:
highlight("foobar Foo bar FOO", "foo")
应该回来 "foobar Foo bar FOO"
我需要代码适用于任何关键字,因此使用硬编码的正则表达式/foo/i
不是一个充分的解决方案.
最简单的方法是什么?
(这是标题中详述的更一般问题的一个例子,但我觉得最好用一个具体的,有用的例子来解决.)
你可以,如果你准备搜索字符串使用正则表达式.在PHP中,例如有一个函数preg_quote,它用转义版本替换字符串中的所有正则表达式.
这是javascript的这样一个函数:
function preg_quote( str ) { // http://kevin.vanzonneveld.net // + original by: booeyOH // + improved by: Ates Goral (http://magnetiq.com) // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + bugfixed by: Onno Marsman // * example 1: preg_quote("$40"); // * returns 1: '\$40' // * example 2: preg_quote("*RRRING* Hello?"); // * returns 2: '\*RRRING\* Hello\?' // * example 3: preg_quote("\\.+*?[^]$(){}=!<>|:"); // * returns 3: '\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:' return (str+'').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1"); }
(摘自http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_preg_quote/)
所以你可以做以下事情:
function highlight( data, search ) { return data.replace( new RegExp( "(" + preg_quote( search ) + ")" , 'gi' ), "$1" ); }
function highlightWords( line, word ) { var regex = new RegExp( '(' + word + ')', 'gi' ); return line.replace( regex, "$1" ); }
您可以使用为您执行特殊字符转义的函数来增强RegExp对象:
RegExp.escape = function(str) { var specials = /[.*+?|()\[\]{}\\$^]/g; // .*+?|()[]{}\$^ return str.replace(specials, "\\$&"); }
然后你就可以使用别人的建议而不用担心:
function highlightWordsNoCase(line, word) { var regex = new RegExp("(" + RegExp.escape(word) + ")", "gi"); return line.replace(regex, "$1"); }
正则表达式很好,只要关键字真的是单词,你可以使用RegExp构造函数而不是文字来从变量创建一个:
var re= new RegExp('('+word+')', 'gi'); return s.replace(re, '$1');
如果"关键字"可以包含标点符号,则会出现困难,因为标点符号往往在正则表达式中具有特殊含义.不像大多数支持regexp的其他语言/库,不存在标准函数来逃避JavaScript中的regexp的标点符号.
并且您不能完全确定哪些字符需要转义,因为并非每个浏览器的regexp实现都保证完全相同.(特别是,较新的浏览器可能会添加新的功能.)并且不能保证反斜杠转义的非特殊字符仍然可以工作,尽管在实践中它可以.
所以你可以做的最好的事情之一是:
试图在今天的常见浏览器中使用每个特殊字符[添加:请参阅Sebastian的配方]
反斜杠 - 逃避所有非字母数字.care:\ W还将匹配您不想要的非ASCII Unicode字符.
只需确保在搜索之前关键字中没有非字母数字
但是,如果您使用它突出显示已经有标记的HTML中的单词,那么您就遇到了麻烦.您的"单词"可能出现在元素名称或属性值中,在这种情况下,尝试在其周围包裹将导致破坏.在更复杂的场景中,甚至可能向XSS安全漏洞注入HTML.如果你必须处理标记,你需要一个更复杂的方法,在尝试自己处理每一段文本之前拆分'<...>'标记.
这样的事情怎么样:
if(typeof String.prototype.highlight !== 'function') {
String.prototype.highlight = function(match, spanClass) {
var pattern = new RegExp( match, "gi" );
replacement = "$&";
return this.replace(pattern, replacement);
}
}
然后可以这样调用:
var result = "The Quick Brown Fox Jumped Over The Lazy Brown Dog".highlight("brown","text-highlight");