Sunday, September 7, 2014

JavaScript: RegExp’s exec() function and String’s match() function

Code(credit to georg) :
re_once = /([a-z])([A-Z])/
re_global = /([a-z])([A-Z])/g

st = "aAbBcC"

console.log("match once=", st.match(re_once), "match global=", st.match(re_global))
console.log("exec once=", re_once.exec(st), "exec global=", re_global.exec(st))
console.log("exec once=", re_once.exec(st), "exec global=", re_global.exec(st))
console.log("exec once=", re_once.exec(st), "exec global=", re_global.exec(st))
Result:
match once= ["aA", "a", "A"] match global= ["aA", "bB", "cC"]

exec once= ["aA", "a", "A"] exec global= ["aA", "a", "A"]
exec once= ["aA", "a", "A"] exec global= ["bB", "b", "B"]
exec once= ["aA", "a", "A"] exec global= ["cC", "c", "C"]

Secrets of the JavaScript Ninja :
using a local regular expression (one without the global flag g) with the String object’s match() methods returns an array containing the entire matched string, along with any matched captures in the operation.

But when we supply a global regular expression (one with the g flag included),match() returns something rather different. It’s still an array of results, but in the case of a global regular expression, which matches all possibilities in the candidate string rather than just the first match,  the array returned contains the global matches; captures within each match aren’t returned in this case.

If captures are important to us, we can regain this functionality while still performing a global search by using the regular expression’s exec() method. This method can be repeatedly called against a regular expression, causing it to return the next matched set of information every time it’s called.

Here a simple example of exec() in action that Steven Levithan put...
I needed to created an array containing the indices of each tab character within a string, so I used something like the following:

var tabIndices = [];
var tabMatchInfo;
var tabRegex = /\t/g;

while (tabMatchInfo = tabRegex.exec(string)) {
     tabIndices.push(tabMatchInfo.index);
}

Nice and easy. To do this without exec, it would require something like the following:

var tabIndices = [];
var thisTabIndex;

for (var i = 0; i < string.length; i++) {
     thisTabIndex = string.indexOf(String.fromCharCode(9), i);
     if (thisTabIndex === -1) {
         break;
     } else {
                tabIndices.push(thisTabIndex);
                i = thisTabIndex;
              }
}

No comments:

Post a Comment