Regex in Javascript: grouping

5

As input from the user I am expecting pairs of numbers separated by commas:

// se for um par só
1-2

// se for mais de um par
1-2,3-4,5-6

I expect something like this:

[
  [1, 2],
  [3, 4],
  [5, 6]
]

I'm in doubt about getting this output in Javascript.

Code so far in JSFiddle (giving infinite loop): link

<input type="text" id="entrada" value="1-2,3-4,5-6"></input>
<button id="botao">Testar</button>
$("#botao").click(function () {
    var regex = new RegExp(/(\d+)-(\d+)/);
    var match;
    var string = $("#entrada").val();
    if (match = regex.exec(string)) {
        while (match !== null) {
            console.log(match);
            match = regex.exec(string)
        }
    } else {
        alert("no match");
    }
});
    
asked by anonymous 18.06.2014 / 18:40

2 answers

5

Simply put, the delimiter for regular expressions is the / toolbar. If you pass a string to the constructor, you should not pass the bars inside the string, otherwise they will be interpreted as literals. Then use this:

var regex = new RegExp(/(\d+)-(\d+)/);

Or so:

var regex = new RegExp("(\d+)-(\d+)");

Note the use of double escapes for digits. One for the string literal and one for the regex itself.

But it does not even make sense to declare the type explicitly, you can just use it like this:

var regex = /(\d+)-(\d+)/;

Now, if you need to use the exec method multiple times in the same string, you should enable the g :

var regex = /(\d+)-(\d+)/g;

Or:

var regex = new RegExp("(\d+)-(\d+)", "g");

That's all, your logic works. But is using regular expressions really necessary? For simple renderings like yours, using a regex is excessive. Aside from being slower, it leaves the code barely readable. You can do the same much more directly.

In this case, you have a parts sequence that uses the comma as a separator

"1-2,3-4,5-6".split(",");
    // => ["1-2", "3-4", "5-6"]

Each of them is a pair separated by a hyphen:

"1-2,3-4,5-6".split(",").map(function(s) {return s.split("-")});
    // => [["1", "2"], ["3", "4"], ["5", "6"]]

You can also transform each string into a number if you want using another level of map .

At a glance: Use regex to search for a pattern within larger text or to override an entry. Do not use regex to parse strings, particularly in these simple cases.

    
18.06.2014 / 19:00
3

Your problem is in while and in the regular expression you are using. To run it multiple times, you have to use the g option. See on the mozilla website.

Use the regular expression: /[(\d-\d)]+/gi

Example

Html:

<ul id="out"></ul>

JavaScript:

var $out = $("#out");
var re = /[(\d-\d)]+/gi
var str = "1-2,3-4,5-6";

do{ 
    var x = re.exec(str);
    if (x == null)
        break; 

    $out.append("<li>" + x + "</li>");
}while(x != null);

The example is here: link

    
18.06.2014 / 19:32