15.5.4.10 String.prototype.match(regexp)

2010-07-10

string|array|null String.prototype.match(regexp:regexp|mixed)

Apply the regular expression to this string and return the result.

This function basically calls the internal (not dynamically fetched) RegExp.prototype.exec function. If regexp is a global regexp, an array of all results of calling exec is returned (or null if it didn't match).

If regexp is global the lastIndex property of regexp will reflect the first character after the last match by exec (0 if none was found). It's actually used as a counter to keep track of what the last position of a matching exec was.

If the regexp is not global, the result of calling exec once is immediately returned.

If regexp is not a regular expression ([[Class]] = "RegExp" or not an object), new RegExp(regexp) is used instead.

The this value is coerced to a string.

Code: (Meta Ecma)
String.prototype.match = function(regexp){
CheckObjectCoercible(this);
var S = ToString(this);
if (Type(regexp) == 'Object' && regexp.[[Class]] == "RegExp") var rx = regexp;
else var rx = new RegExp(regexp);
var global = rx.[[Get]]("global");
var exec = RegExp.prototype.exec; // should be the built-in version, 15.10.6.2
if (!global) return exec.[[Call]](rx, [S]);
rx.[[Put]]("lastIndex", 0);
var A = new Array;
var previousLastIndex = 0;
var n = 0;
var lastMatch = true;
while (lastMatch) {
var result = exec.[[Call]](rx, [S]);
if (result === null) lastMatch = false;
else {
var thisIndex = rx.[[Get]]("lastIndex");
if (thisIndex === previousLastIndex) {
rx.[[Put]]("lastIndex", thisIndex+1);
previousLastIndex = thisIndex + 1;
} else {
previousLastIndex = thisIndex;
}
var matchStr = result.[[Get]]("0");
A.[[DefineOwnProperty]](ToString(n), PD{[[Value]]:matchStr, [[Writable]]:true, [[Enumerable]]:true, [[Configurable]]:true}, false);
++n;
}
}
if (n == 0) return null;
return A;
}