Javascript:突出显示保持原始大小写的子字符串,但在不区分大小写的模式下搜索

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3294576/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 00:46:14  来源:igfitidea点击:

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

javascriptregexcase-sensitivecase-insensitive

提问by Giovanni Di Milia

I'm trying to write a "suggestion search box" and I cannot find a solution that allows to highlight a substring with javascript keeping the original case.

我正在尝试编写一个“建议搜索框”,但找不到允许使用 javascript 突出显示子字符串并保留原​​始大小写的解决方案。

For example if I search for "ca" I search server side in a case insensitive mode and I have the following results:

例如,如果我搜索“ ca”,我会在不区分大小写的模式下搜索服务器端,然后得到以下结果:

Calculator

计算器

calendar

日历

ESCAPE

逃脱

I would like to view the search string in all the previous words, so the result should be:

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

Calculator

lculator

calendar

CAlendar

ESCAPE

ES CAPE

I tried with the following code:

我尝试使用以下代码:

var reg = new RegExp(querystr, 'gi');
var final_str = 'foo ' + result.replace(reg, '<b>'+querystr+'</b>');
$('#'+id).html(final_str);

But obviously in this way I loose the original case!

但显然这样我就弄丢了原来的箱子!

Is there a way to solve this problem?

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

回答by user113716

Use a function for the second argument for .replace()that returns the actual matched string with the concatenated tags.

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

Try it out:http://jsfiddle.net/4sGLL/

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

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

JSFiddle Example with Input:https://jsfiddle.net/pawmbude/

带输入的 JSFiddle 示例:https ://jsfiddle.net/pawmbude/

回答by serby

ES6 version

ES6版本

const highlight = (needle, haystack) =>
  haystack.replace(new RegExp(needle, 'gi'), str => `<strong>${str}
</strong>`)

回答by rosenfeld

While the other answers so far seem simple, they can't be really used in many real world cases as they don't handle proper text HTML escaping and RegExp escaping. If you want to highlight every possible snippet, while escaping the text properly, a function like that would return all elements you should add to your suggestions box:

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

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
    hl.innerText = m
    left = right.slice(0, i)
    right = right.slice(i + m.length)
    result.push(document.createTextNode(left), hl)
    if (!right.length) return result
  }
  result.push(document.createTextNode(right))
  return result
}

回答by NVRM

Not exactly perfect as it replace all by lower char:

不完全完美,因为它全部替换为较低的字符:

let ? = document.body
function check(_?){
_?_ = new RegExp(_?, "ig") 
?.innerHTML=?.innerHTML.replace(_?_,"<b>"+_?+"</b>")
}

check('ca')
Calculator

calendar

ESCAPE

Cardan de voiture cassé

回答by PradeepKN

Highlight search term and anchoring to first occurence - Start

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

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
}

Highlight search term and anchoring to first occurence - End

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

回答by Cyril Jacquart

nice results with

不错的结果

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;"><b>'+str+'</b></span>'});
}

and easier to remember... thx to user113716: https://stackoverflow.com/a/3294644/2065594

并且更容易记住......感谢user113716:https://stackoverflow.com/a/3294644/2065594

回答by Larry K

I do the exact same thing.

我做同样的事情。

You need to make a copy.

你需要复印一份。

I store in the db a copy of the real string, in all lower case.

我在数据库中存储了一个真实字符串的副本,全部小写。

Then I search using a lower case version of the query string or do a case insensitive regexp.

然后我使用查询字符串的小写版本进行搜索或执行不区分大小写的正则表达式。

Then use the resulting found start index in the main string, plus the length of the query string, to highlight the query string within the result.

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

You can not use the query string in the result since its case is not determinate. You need to highlight a portion of the originalstring.

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

回答by jasongetsdown

.match()performs case insensitive matching and returns an array of the matches with case intact.

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

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) + '<b>' + match + '</b>';
    startHere = nextMatch + qLength;
}

回答by Avinash

I have found a easiest way to achieve it. JavaScript regular expression remembers the string it matched. This feature can be used here.

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

I have modified the code a bit.

我稍微修改了代码。

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