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

不羁的心 提交于 2019-11-28 17:52:59
user113716

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

Try it out: 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/

ES6 version

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

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é

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 original string.

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

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:

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
}

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

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

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;
}

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

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);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!