Replace javascript modifies only the last term

Asked

Viewed 99 times

1

I’m using javascript code to bold the searched terms, but if the term repeats it changes only the last one and also I wish it wasn’t case sensitive:

for example, in the string: Brilha o Sol, como brilha o Sol do meio dia
stays: `The Sun shines like glow the Sol midday.

$q = 'Sol brilha'
var searchTerm = $q.split(" ");
 
$(".resultado").each(function() {
    var html = $(this).html().toString();
    for(var i = 0; i < searchTerm.length; i++) {
        var pattern = "([^\w]*)(" + searchTerm[i] + ")([^\w]*)";
        var rg = new RegExp(pattern);
        var match = rg.exec(html);
        if(match) {
            html = html.replace(rg,match[1] + "<b>"+ match[2] +"</b>" + match[3]);
            $(this).html(html);
        }
    }
});

1 answer

3


Let’s go step by step.

Searching words with Regexp

One of the ways to search a word is to use the metacharacter \b, or Word Boundary, available in Regex. With it, there are three different positions that qualify as word limits:

  • Before the first character of the text, if the first character is a word character.
"Brilha o Sol, como brilha o Sol do meio dia brilhantemente".match(/\Bbrilha/gi)
// Output: ["Brilha", "brilha", "brilha"]
  • After the last character of the text, if the last character is a word character.
"Brilha o Sol, como brilha o Sol do meio dia brilhantemente".match(/Brilha\b/gi)
// Output: ["Brilha", "brilha"]
  • Between two characters in the text, where one is a word character and the other is not a word character.
"Brilha o Sol, como brilha o Sol do meio dia brilhantemente".match(/\bBrilha\b/gi)
// Output: ["Brilha", "brilha"]

Simplifying: \b allows you to search entire words.

Searching terms with case-insensitive

When we instantiate the class/function RegExp in the Javascript, we can get through flags that can help us. One of these is i, which means to ignore capital. /ore. The other, g, which corresponds to the global search, that is, it finds all the correspondence instead of stopping after finding the first.

Refactoring

Instead of using ([^\w]*) to find the terms before and after the word we want to find, I started using the symbol of pipe |. When we use it (\b(brilha|sol)\b), we are informing that we want to seek both the term glow how much sun. This avoids a loop unnecessary and improves long text performance.

In function String.replace, I chose to use substrings, as second parameter, to add the word within the tag Bold. We can use substring as follows: $n or $nn where n or nn are integer numeric values that inserts the nth substring in brackets (called groups), given the first argument was an object Regexp.

Sample code:

$q = 'sol brilha'
var searchTerm = $q.split(" ");
 
$(".resultado").each(function() {
    var html = $(this).html().toString();
    var pattern = "\\b(" + searchTerm.join('|') + ")\\b";
    var rg = new RegExp(pattern, 'ig');
    var match = rg.exec(html);

    html = html.replace(rg, "<b>$1</b>");
    $(this).html(html);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="resultado">Brilha o Sol, como brilha o Sol do meio dia</div>

  • Have any need for the if (match) {? I think that, if there is no replace just won’t do anything, right? Because the way it is, theoretically two "sweeps" are being made.

  • @Luizfelipe Truth! Thank you for the touch.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.