关于正则表达式:Javascript:突出显示保留原始案例的子字符串,但在不区分大小写模式下搜索

Javascript: highlight substring keeping original case but searching in case insensitive mode

我正试图写一个"建议搜索框",但我找不到一个解决方案,可以用保留原始大小写的javascript突出显示子字符串。

例如,如果我在不区分大小写的模式下搜索"ca",则会得到以下结果:

计算器

日历

逃逸

我想查看前面所有单词中的搜索字符串,因此结果应该是:

计算器

日历

逃逸

我尝试使用以下代码:

1
2
3
var reg = new RegExp(querystr, 'gi');
var final_str = 'foo ' + result.replace(reg, ''+querystr+'');
$('#'+id).html(final_str);

但很明显,这样我就松开了原来的箱子!

有没有办法解决这个问题?


.replace()的第二个参数使用一个函数,该函数返回带有连接标记的实际匹配字符串。

试试看:http://jsfiddle.net/4sgll/

1
2
3
4
5
reg = new RegExp(querystr, 'gi');
       // The str parameter references the matched string
       //    --------------------------------------v
final_str = 'foo ' + result.replace(reg, function(str) {return ''+str+''});
$('#' + id).html(final_str);?

jfiddle输入示例:https://jsfiddle.net/pawmbude/


ES6版本

1
2
3
const highlight = (needle, haystack) =>
  haystack.replace(new RegExp(needle, 'gi'), str => `${str}
`)


不完全完美,因为它用小写字符替换了所有字符:

1
2
3
4
5
6
7
let ? = document.body
function check(_?){
_?_ = new RegExp(_?,"ig")
?.innerHTML=?.innerHTML.replace(_?_,""+_?+"")
}

check('ca')
1
2
3
4
5
6
7
Calculator

calendar

ESCAPE

Cardan de voiture cassé


突出显示搜索项并锚定到第一次出现-开始

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function highlightSearchText(searchText) {
    var innerHTML = document.documentElement.innerHTML;
    var replaceString = '<mark>'+searchText+'</mark>';
    var newInnerHtml = this.replaceAll(innerHTML, searchText, replaceString);
    document.documentElement.innerHTML = newInnerHtml;
    var elmnt = document.documentElement.getElementsByTagName('mark')[0]
    elmnt.scrollIntoView();
}

function replaceAll(str, querystr, replace) {
    var reg = new RegExp(querystr, 'gi');
    var final_str = str.replace(reg, function(str) {return '<mark>'+str+'</mark>'});
    return final_str
}

突出显示搜索项并锚定到第一次出现-结束


虽然到目前为止其他的答案看起来很简单,但它们不能真正用于许多实际情况,因为它们不能处理正确的文本HTML转义和regexp转义。如果您想突出显示每一个可能的代码片段,同时正确地转义文本,这样的函数将返回您应该添加到建议框中的所有元素:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function highlightLabel(label, term) {
  if (!term) return [ document.createTextNode(label) ]
  const regex = new RegExp(term.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&'), 'gi')
  const result = []
  let left, match, right = label
  while (match = right.match(regex)) {
    const m = match[0], hl = document.createElement('b'), i = match.index
    b.innerText = m
    left = right.slice(0, i)
    right = right.slice(i + m.length)
    result.push(createTextNode(left), hl)
    if (!right.length) return result
  }
  result.push(createTextNode(right))
  return result
}

很好的结果

1
2
3
4
function str_highlight_text(string, str_to_highlight){
   var reg = new RegExp(str_to_highlight, 'gi');
   return string.replace(reg, function(str) {return '<span style="background-color:#ffbf00;color:#fff;">'+str+'</span>'});
}

更容易记住…THX到用户113716:https://stackoverflow.com/a/3294644/2065594


我也做同样的事。

你需要复印一份。

我在数据库中存储了一个真正字符串的副本,在所有小写的情况下。

然后我使用查询字符串的小写版本进行搜索,或者执行不区分大小写的regexp。

然后,使用主字符串中找到的开始索引,加上查询字符串的长度,突出显示结果中的查询字符串。

不能在结果中使用查询字符串,因为它的大小写不确定。您需要突出显示原始字符串的一部分。


我找到了一个最简单的方法来实现它。javascript正则表达式记住它匹配的字符串。此功能可在此处使用。

我对代码做了一些修改。

1
2
3
reg = new RegExp("("+querystr.trim()+")", 'gi');
final_str = 'foo ' + result.replace(reg,"&1");
$('#'+id).html(final_str);


.match()执行不区分大小写的匹配,并返回一个大小写完整的匹配数组。

1
2
3
4
5
6
7
8
9
10
11
var matches = str.match(queryString),
    startHere = 0,
    nextMatch,
    resultStr ='',
    qLength = queryString.length;

for (var match in matches) {
    nextMatch = str.substr(startHere).indexOf(match);
    resultStr = resultStr + str.substr(startHere, nextMatch) + '' + match + '';
    startHere = nextMatch + qLength;
}