Search code examples
jqueryarraysarray-map

How to check if string matches pattern given?


Have a string like this: 'XXX-XXX-XXX'; This can be changed by the user. Than I have another string like this, that uses characters in this string to generate a serial number: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; This can be changed by the user.

Now, I need to loop through a bunch of input values to determine if they match the formula (will always be only X's and dashes. Note: dashes might not even exist in formula, this is user defined and can change from within a different input field altogether).

Basically, there is another group of input fields:

<div class="check_these">
    <input type="text" class="p-serials" name="pserials[]" value="YER-CGH-JOP" />
    <input type="text" class="p-serials" name="pserials[]" value="BAB-CC1-D80" />
    <input type="text" class="p-serials" name="pserials[]" value="JUQ-P" />
    <input type="text" class="p-serials" name="pserials[]" value="XXX-XXX-XXX" />
</div>

So, we have the var formula = 'XXX-XXX-XXX'; variable and the possible characters that are allowed in the string var chrs = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';

So, how to change this code below so that it returns only those that match:

var currMatches = $(".p-serials").map(function () {
    // Need to match only formula numbers in here!
    return $(this).val();
}).get();

So, according to the inputs above, currMatches should be equal to this: ["YER-CGH-JOP", "XXX-XXX-XXX"]

Since these are the only ones that match the formula and characters allowed.


Solution

  • It's a little unsightly, but you could use the string of allowed characters and the provided pattern string to build a Regex using string replacement of the X. From there you can loop over the inputs and test the values against the expression. Something like this:

    var chrs = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; // assume this is retrieved from a user input
    var format = 'XXX-XXX-XXX'; // assume this is retrieved from a user input
    var re = new RegExp('^' + format.replace(/X/g, "[" + chrs + "]") + '$');
    
    var currMatches = $(".p-serials").map(function () {
        if (re.test(this.value))
            return this.value;
        return;
    }).get();
    

    Example fiddle

    If you want to make the Regex case-insensitive, you can add the flag to the constructor:

    new RegExp('^' + format.replace(/X/g, "[" + chrs + "]") + '$', 'i')
    

    Also note that you would need to do a lot of string sanitisation on this to ensure the user input doesn't interfere with recognised Regex operators.