Jean-philippe Emond
Jean-philippe Emond

Reputation: 1614

JS regex: unable to return array matches

I Have a form with multiple input text like:

<div class="width-height">
    <input value="" name="items[1][width]" type="text">
    <br>
    <input value="" name="items[1][height]" type="text">
</div>
 <div class="width-height">
    <input value="" name="items[2][width]" type="text">
    <br>
    <input value="" name="items[2][height]" type="text">
</div>

I try to get with a JS foreach "number" and "width" or "height" in an array

the best result possibility should be an array with 2 value in console.log:

1,width
1,height
2,width
2,height

I try 2 regex :

// first: /\d\]\[[a-z]+/i
// second: /\d\]\[\w+/g
$('.width-height > input').each(function () {
    console.log("1 : " + $(this).attr('name').match(/\d\]\[[a-z]+/i));
    console.log("2 : " +  $(this).attr('name').match(/\d\]\[\w+/g));
});

but the result is only:

1 : 1][width
2 : 1][width

I have tried to use uncapture setting for excluding part that I don't need :

console.log("3 : " +  $(this).attr('name').match(/(?:\w+\[)\d(?:\]\[)\w+/g));

but it return only 1 string

3 : items[1][width

I guess I don't understand something in regex.. with non-capture and "g" flag i think it should return all possibility without capture and build an array with retrieving value but .. not.. :-/

Tranks for your help!

Upvotes: 0

Views: 85

Answers (4)

1252748
1252748

Reputation: 15389

If you're interested in doing this without jQuery, this will return to you an array of your requested output.

var inputs = document.querySelectorAll("input[type=text]");
var result = Array.prototype.slice.call(inputs).map(function(el){
   return el.getAttribute("name").replace(/.*\[(\d+)\]\[(\w+)\].*$/, "$1,$2");                                      
});
console.log(result);

JSBIN

REGEX

Upvotes: 0

Ammadu
Ammadu

Reputation: 1675

Try this

$('.width-height > input').each(function () {
    var matches = $(this).attr('name').match(/[\d]?[\w]+/gi);     
    console.log(matches.splice(1));   
});

Upvotes: 0

Quentin
Quentin

Reputation: 944556

A non-capturing group doesn't exclude any data from the whole match, it just won't appear in the list of captured groups.

You need to use capturing groups to handle this (which also means you can't use match).

A capturing group is delimited with ( and ).

$('.width-height > input').each(function () {
    var regex = /(\d)\]\[(\w+)/;
    var matches = regex.exec($(this).attr('name'));
    console.log(matches[1] + "," + matches[2]);
});

Upvotes: 3

dakab
dakab

Reputation: 5915

Try this straight-forward, native approach:

var inputs = document.querySelectorAll('div.width-height > input[name^="items"]');
var result = [];
var match = null;

Array.prototype.forEach.call(inputs,function(input){
    match = input.name.match(/^items\[(\d)\]\[(width|height)\]$/);
    if(match.length===3)
        result.push([match[1],match[2]]);
});

console.log( result );

Did you mean an array of arrays by “array with 2 value”? If the format of the name attribute value isn’t that static, it would be just a minor change in the regex. Or did you wish to have your regex explained?

Upvotes: 1

Related Questions