You usually want to match some arbitrary text in a case insensitive way. Sometimes, search queries contain characters that are special regex metacharacters and must be escaped before compiling the pattern.
Use a solution like
var words = ["cows", "c++", "$var$"];
$("h2").html(function(_, html) {
return html.replace(new RegExp(words.map(function(x) {
return x.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
}).join('|'), "gi"), '<span class="smallcaps">$&</span>')
});
span { color: red}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h2>We have cows on our farm</h2>
<h2>C++ Apps $var$</h2>
Note that here, a regex will look like /cows|c\+\+|\$var\$/gi
, where +
and $
, special regex metacharacters, are escaped, and the alternatives are ORed with the |
alternation operator.
Also, note that there is no need of any outer parentheses as the default group is Group 0 that holds the whole match, and the backreference to Group 0 in JavaScript regex is $&
. Thus, the replacement is always done with the search word in the exact case as it was found in text.
Note that in case you need to match whole words only, you would need special boundaries, either \b
(if the search words always consist of letters, digits or _
) or (\W|^)
/ (?!\w)
(if there can be special characters):
var words = ["cows", "c++", "$var$"];
$("h2").html(function(_, html) {
return html.replace(new RegExp("(\\W|^)(" + words.map(function(x) {
return x.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
}).join('|') + ")(?!\\w)", "gi"), '$1<span class="smallcaps">$2</span>')
});
span { color: red}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h2>We have cows in our farm cowshed</h2>
<h2>C++ Apps $var$ in $var$moretext</h2>