1

I need to compare two strings in a loop while accepting a certain character "-" within the matching string.

function onDatabound(e) 
{
    var grid = e.sender;
    var str = $.trim(grid.value());
    var srcWords = str.split(" ");
    var records = $(grid.ul).find("li");
    for (var i = 0; i < records.length; i++) {
        var classes = $(records[i]).find("span i").attr("class");
        var newText = records[i].innerText;
        for (var j = 0; j < srcWords.length; j++) {
            var regex = new RegExp(srcWords[j], 'gi'); //case-insensitive
            newText = newText.replace(regex,
                function(match) {
                    return '<strong>' + match + '</strong>';
                });
        }
        $(records[i]).find("span").html("<i class='" + classes + "'></i>" +  newText);
    }
}

This code works perfectly but it needs the final touch. I need the replace-function to also accept inputs from users even if they don´t write the character "-". Example:

innerText: 1111-2222 lorem ipsum dolar 11112222 lorem ipsum dolar

User input: 11112222

I need both of these to be highlighted "1111-2222" and "11112222" even though the user wrote without the "-" or vice versa.

Should I use the regular expression to solve this or do you guys see any other method for me to use?

gardarvalur
  • 1,565
  • 9
  • 39
  • 65
  • 1
    Try `new RegExp(srcWords[j].split("").join("-?"), 'gi')` – Wiktor Stribiżew Nov 05 '19 at 10:45
  • OMG! Thank you @WiktorStribiżew, that worked. That didn´t take long. Can you please post this as answer so I can mark it as correct? :) – gardarvalur Nov 05 '19 at 10:47
  • To avoid run-time errors, you also should use regex-escape before constructing regular expressions from arbitrary strings: `new RegExp(srcWords[j].split('').map(RegExp.escape).join('-?'), 'gi')`. The (`RegExp.escape()` function is [this one](https://stackoverflow.com/a/3561711/18771).) – Tomalak Nov 05 '19 at 10:53

1 Answers1

1

While you are building the regex dynamically, it makes sense to insert an optional hyphen between each char.

You may build the pattern using

var regex = new RegExp(srcWords[j].split("").join("-?"), 'gi');

Here is a sample demo of the regex.

With escaping special chars:

var regex = new RegExp(srcWords[j].split("").map(function(s) { 
  return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
} ).join("-?"), 'gi');

Note you do not need an anonymous callback method in the replacement to replace with the whole match, you may use a plain $& string backreference:

newText = newText.replace(regex,'<strong>$&</strong>');

See Difference between $1 and $& in regular expressions

JS demo:

var newText = "1111-2222 and 11112222";
var srcWords = "11112222";
var regex = new RegExp(srcWords.split("").map(function(s) { 
  return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
} ).join("-?"), 'gi');
console.log( newText.replace(regex,'<strong>$&</strong>') );
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • 1
    Thank you for that, I changed my code accordingly with your second suggestion. I see now that I don´t need the callback function. Thanks again. – gardarvalur Nov 05 '19 at 10:56
  • btw @WiktorStribiżew, do you think I need to map that callback function with the crazy looking regex? (the other thing works) – gardarvalur Nov 05 '19 at 11:05
  • @gardarvalur If the input may contain chars like `(`, `)`, `[`, `?`, `+`... then you have to. – Wiktor Stribiżew Nov 05 '19 at 11:07
  • hmmm I see. I´ll keep that in mind but as this particular system section concerns it shouldn´t include those characters anyway. Thanks again – gardarvalur Nov 05 '19 at 11:09