Regex in Javascript: grouping

Asked

Viewed 343 times

5

As input by 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 to come out:

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

I’m in doubt on how to get this output in Javascript.

Code so far in Jsfiddle (is giving infinite loop): http://jsfiddle.net/cbLs8/7/

<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");
    }
});
  • How about /((\d+)-(\d+))+/?

  • Is this what you want?: http://jsfiddle.net/cbLs8/8/

2 answers

5


Simply put, the delimiter for regular expressions is the bar /. If you pass a string to the constructor, you should not pass the bars inside the string, but they will be interpreted as literal. So use:

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 doesn’t even make sense to state the type explicitly, you can just use it like this:

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

Now, if you need to use the method exec multiple times in the same string, you must enable the option 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 processing like yours, using a regex is excessive. In addition to being slower, it leaves the code barely readable. You can do the same much more directly.

In this case, you have a sequence of parts 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 even turn each string into a number if you want using another level of map.

In summary: Use regex to search for a pattern within a larger text or to validate by setting an entry. Do not use regex to parse strings, in particular in these simple cases.

  • 1

    Can you highlight the last part? "Why regex" was the first thing I thought when I read the question.

  • @bfavaretto explained a little more.

  • Valeu Guilherme!

  • 1

    Perfect! I appreciate the suggestion Guilherme and @bfavaretto, really it is much simpler like this, with split and map. =)

  • To those interested in seeing on Jsfiddle: http://jsfiddle.net/PU5CZ/2/

3

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

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: http://jsfiddle.net/andrenmaia/sNHqD/4/

  • Your answer was helpful, I didn’t know you had to have the g. Thank you!

Browser other questions tagged

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