Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Case insensitive string replacement in JavaScript?

People also ask

Is JavaScript string replace case-sensitive?

JavaScript String Replace | Case Insensitive. The . replace function in JavaScript helps developers replace all the occurrences of a string in a text. However, many of us developers use this method in the wrong way while writing the code.

How do you make a case insensitive in JavaScript?

The best way to do a case insensitive comparison in JavaScript is to use RegExp match() method with the i flag.

What is $1 in replace JavaScript?

In your specific example, the $1 will be the group (^| ) which is "position of the start of string (zero-width), or a single space character". So by replacing the whole expression with that, you're basically removing the variable theClass and potentially a space after it.

What is case insensitive in JavaScript?

Comparing strings in a case insensitive manner means to compare them without taking care of the uppercase and lowercase letters. To perform this operation the most preferred method is to use either toUpperCase() or toLowerCase() function.


You can use regular expressions if you prepare the search string. In PHP e.g. there is a function preg_quote, which replaces all regex-chars in a string with their escaped versions.

Here is such a function for javascript (source):

function preg_quote (str, delimiter) {
  //  discuss at: https://locutus.io/php/preg_quote/
  // original by: booeyOH
  // improved by: Ates Goral (https://magnetiq.com)
  // improved by: Kevin van Zonneveld (https://kvz.io)
  // improved by: Brett Zamir (https://brett-zamir.me)
  // bugfixed by: Onno Marsman (https://twitter.com/onnomarsman)
  //   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(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&')
}

So you could do the following:

function highlight(str, search) {
    return str.replace(new RegExp("(" + preg_quote(search) + ")", 'gi'), "<b>$1</b>");
}

function highlightWords( line, word )
{
     var regex = new RegExp( '(' + word + ')', 'gi' );
     return line.replace( regex, "<b>$1</b>" );
}

You can enhance the RegExp object with a function that does special character escaping for you:

RegExp.escape = function(str) 
{
  var specials = /[.*+?|()\[\]{}\\$^]/g; // .*+?|()[]{}\$^
  return str.replace(specials, "\\$&");
}

Then you would be able to use what the others suggested without any worries:

function highlightWordsNoCase(line, word)
{
  var regex = new RegExp("(" + RegExp.escape(word) + ")", "gi");
  return line.replace(regex, "<b>$1</b>");
}

Regular expressions are fine as long as keywords are really words, you can just use a RegExp constructor instead of a literal to create one from a variable:

var re= new RegExp('('+word+')', 'gi');
return s.replace(re, '<b>$1</b>');

The difficulty arises if ‘keywords’ can have punctuation in, as punctuation tends to have special meaning in regexps. Unfortunately unlike most other languages/libraries with regexp support, there is no standard function to escape punctation for regexps in JavaScript.

And you can't be totally sure exactly what characters need escaping because not every browser's implementation of regexp is guaranteed to be exactly the same. (In particular, newer browsers may add new functionality.) And backslash-escaping characters that are not special is not guaranteed to still work, although in practice it does.

So about the best you can do is one of:

  • attempting to catch each special character in common browser use today [add: see Sebastian's recipe]
  • backslash-escape all non-alphanumerics. care: \W will also match non-ASCII Unicode characters, which you don't really want.
  • just ensure that there are no non-alphanumerics in the keyword before searching

If you are using this to highlight words in HTML which already has markup in, though, you've got trouble. Your ‘word’ might appear in an element name or attribute value, in which case attempting to wrap a < b> around it will cause brokenness. In more complicated scenarios possibly even an HTML-injection to XSS security hole. If you have to cope with markup you will need a more complicated approach, splitting out ‘< ... >’ markup before attempting to process each stretch of text on its own.