0

Below is the function which add html bold tag to sub-string we passed.

function boldString(str, find) {
    var re = new RegExp(find, 'g');
    return str.replace(re, '<b>' + find + '</b>');
}  

console.log(boldString("this is for testing purpose","testing"));
console.log(boldString("testing with (parentheses)","(parentheses)"));

Why in second case output is not as expected?

melpomene
  • 79,257
  • 6
  • 70
  • 127
arjun kr
  • 523
  • 4
  • 16

2 Answers2

3

Parentheses are a reserved symbol in regular expressions. You would bump into the same problem with e.g. ., +, *, [] etc.

You'll want to add escape characters to the text before constructing a regexp out of it. (Also, it's better to use .replace()s function-accepting form and use the actual match string.)

function escapeRegExp(str) {
  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}

function boldString(str, find) {
    var re = new RegExp(escapeRegExp(find), 'g');
    return str.replace(re, function (m) {
      return '<b>' + m + '</b>';
    });
}
AKX
  • 93,995
  • 11
  • 81
  • 98
1

Because ( and ) (and several other characters) have special meaning in regular expressions, and you haven't escaped them. You'd need to pass in "\\(parentheses\\)": The first backslash escapes the second in the string literal so that the string actually contains a backslash; that backslash in the string escapes the ( and ).

Example:

function boldString(str, find) {
    var re = new RegExp(find, 'g');
    return str.replace(re, '<b>' + find + '</b>');
}  

console.log(boldString("this is for testing purpose","testing"));
console.log(boldString("testing with (parentheses)","\\(parentheses\\)"));

Of course, without changing your boldString's inputs, that's going to include the backslashes in the output as well. As melpomene pointed out in a comment, you can fix that by using $& as the replacement, which will be the text matched by the exppression:

function boldString(str, find) {
    var re = new RegExp(find, 'g');
    return str.replace(re, '<b>$&</b>');
}  

console.log(boldString("this is for testing purpose","testing"));
console.log(boldString("testing with (parentheses)","\\(parentheses\\)"));

If you're accepting end-user input, this question's answers have functions you can use to add any necessary escapes. For instance, using the one from the currently-accepted answer:

RegExp.escape= function(s) {
    return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
};

function boldString(str, find) {
    var re = new RegExp(RegExp.escape(find), 'g');
    return str.replace(re, '<b>' + find + '</b>');
}  

console.log(boldString("this is for testing purpose","testing"));
console.log(boldString("testing with (parentheses)","(parentheses)"));
T.J. Crowder
  • 879,024
  • 165
  • 1,615
  • 1,639