Javascript - Regex access multiple occurrences [duplicate]

I have this text

txt = "Local residents o1__have called g__in o22__with reports...";

in which I need to get the list of numbers between each o and __

If I do

txt.match(/o([0-9]+)__/g);

I will get

["o1__", "o22__"]

But I'd like to have

["1", "22"]

How can I do that ?

Answers:

Answer

See this question:

txt = "Local residents o1__have called g__in o22__with reports...";
var regex = /o([0-9]+)__/g
var matches = [];
var match = regex.exec(txt);
while (match != null) {
    matches.push(match[1]);
    match = regex.exec(txt);
}
alert(matches);
Answer

You need to use .exec() on a regular expression object and call it repeatedly with the g flag to get successive matches like this:

var txt = "Local residents o1__have called g__in o22__with reports...";
var re = /o([0-9]+)__/g;
var matches;
while ((matches = re.exec(txt)) != null) {
    alert(matches[1]);
}

The state from the previous match is stored in the regular expression object as the lastIndex and that's what the next match uses as a starting point.

You can see it work here: http://jsfiddle.net/jfriend00/UtF6J/

Using the regexp this way is described here: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp/exec.

Answer
/o([0-9]+?)__/g

This should work. Click here and search for "lazy star".

var rx = new RegExp( /o([0-9]+?)__/g );
var txt = "Local residents o1__have called g__in o22__with reports...";
var mtc = [];
while( (match = rx.exec( txt )) != null ) {
        alert( match[1] );
        mtc.push(match[1]);
}

Jek-fdrv pointed out in the comments, that if you call rx.test just before the while loop some results are skipped. That's because RegExp object contains a lastIndex field that keeps track of last match's index in the string. When lastIndex changes then RegExp keeps matching by starting from it's lastIndex value, therefore a part of the string is skipped. A little example may help:

var rx = new RegExp( /o([0-9]+?)__/g );
var txt = "Local residents o1__have called g__in o22__with reports...";
var mtc = [];
console.log(rx.test(txt), rx.lastIndex); //outputs "true 20"
console.log(rx.test(txt), rx.lastIndex); //outputs "true 43"
console.log(rx.test(txt), rx.lastIndex); //outputs "false 0" !!!
rx.lastIndex = 0; //manually reset lastIndex field works in Chrome
//now everything works fine
while( (match = rx.exec( txt )) != null ) {
        console.log( match[1] );
        mtc.push(match[1]);
}

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.