Adding a firstIndex argument to string.search seems like an incomplete proposal
to me. IMO, if it were to be added there, it should also be added at least to
regexp.test, regexp.exec, and string.match when given a nonglobal regex (in
which case it’s an alias for regexp.exec). It could also be useful, though
probably far less frequently, with string.split, string.replace, and
string.match (when given a global regex).
Using regexp.lastIndex together with regexp.exec and /g in order to pull this
off is indeed ugly (and runs into issues with IE8-minus for zero-length
matches), but at least it provides a mechanism that lets you build your own
sugar.
The “^” metacharacter (and potential future regex syntax) is not the only thing
to consider if adding an alternative mechanism to set the starting position for
a regex. There is also the interplay with flag /y (no biggie, just something to
keep in mind), and more importantly the conflict with the lastIndex property
for global regexes. I’d like to see both the lastIndex and global properties of
regexps be deprecated altogether, in which case what you’re pitching would be
perfectly reasonable. But that would require broader changes, and I don’t
expect such ideas to be tackled (much less see TC-39 consensus) in time for ES6.
In the XRegExp library, I provide an argument like you’re proposing for my own
exec and test methods, but this can only be done cleanly since I always ignore
lastIndex as the search start position. Here’s the code, in case you’re
interested. (The private `copy` function used here accepts flags to add via the
second arg, and flags to remove via the third arg.)
XRegExp.exec = function (str, regex, pos, sticky) {
var r2 = copy(regex, "g" + (sticky && hasNativeY ? "y" : ""), (sticky ===
false ? "y" : "")),
match;
r2.lastIndex = pos = pos || 0;
match = fixed.exec.call(r2, str); // Fixed `exec` required for `lastIndex`
fix, etc.
if (sticky && match && match.index !== pos) {
match = null;
}
if (regex.global) {
regex.lastIndex = match ? r2.lastIndex : 0;
}
return match;
};
--Steven Levithan
From: Felix Böhm
Sent: Friday, April 20, 2012 2:20 PM
To: [email protected]
Subject: fromIndex for String.prototype.search
In December of 2009, there was already a related proposal [1] (which pretty
much got ignored at that time), but I wanted to ask only for a subset of it:
When building parsers, the second argument of String.prototype.indexOf (named
firstIndex) is pretty helpful to speed things up. A simple index can be used to
track the current position. In more general cases (with more than just a
handful of separators), String.prototype.search appears to be the better
choice. But lacking the firstIndex parameter, it requires to use
String.prototype.substr after each iteration. This leads to slow and
bad-looking code. But there's a solution: A firstIndex parameter for
String.prototype.slice.
A polyfill could look like this (expecting that the number of arguments is
increased to 2):
if (String.prototype.search.length === 1) {
String.prototype.search = (function (oldSearch) {
return function (re, fromIndex) {
if (typeof fromIndex !== "number") return oldSearch.call(this, re);
var result = oldSearch.call(this.substr(0, fromIndex), re)
return result === -1 ? result : result + fromIndex;
};
})(String.prototype.search);
}
The only reason I can think of why this might be a bad idea is the "^"
metacharacter, as it's accepting the new position as the start of the string.
The optimal/expected behavior in this case might need some discussion (even
though the solution above eases polyfilling a lot).
The only response to the old proposal suggested using re.lastIndex, what's just
ugly and feels hacky.
[1] https://mail.mozilla.org/pipermail/es-discuss/2009-December/010505.html
--------------------------------------------------------------------------------
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss