|
View:
New views
6 Messages
—
Rating Filter:
Alert me
|
|
|
String#replace String#match and regexp.lastIndexHi,
I noticed in the ECMA 5 draft that String#replace references String#match's handling of regexp.lastIndex when the regexp is flagged global. According to the draft String#match sets the regexp.lastIndex when the regexp is global. Currently Firefox, Chrome, Safari, Opera do not set the lastIndex on String#match or String#replace. IE does set the lastIndex but only once, not during each internal iteration of `Repeat, while lastMatch is true`, and for non-global regexp's as well. According to spec I would expect: var s = '0x2x4x6x8'; var p = /x/g; s.replace(p, function() { alert(p.lastIndex) }); // A: alerts 2, then 4, then 6, then 8 alert(p.lastIndex); // B: alerts 0 because internal exec returned null (which set lastIndex 0) triggering the end of the iteration; // IE7 // A: alerts 0, then 0, then 0, then 0 // B: alerts 8 // All others // A: alerts 0, then 0, then 0, then 0 // B: alerts 0 This might be a compatibility issue to consider. - John-David Dalton _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: String#replace String#match and regexp.lastIndex> I noticed in the ECMA 5 draft that String#replace references
> String#match's handling of regexp.lastIndex > when the regexp is flagged global. According to the draft String#match > sets the regexp.lastIndex when the regexp is global. All of this is identical to ECMA-262 Edition 3. > Currently Firefox, Chrome, Safari, Opera do not set the lastIndex on > String#match Yes they do. Leaving aside whatever happens during the matching process (since it's unobservable to users), String#match called with a "global" RegExp always starts searching from index 0 and the RegExp's lastIndex is always 0 after after the method is complete. (That is, except in IE, which has the bug you mentioned where lastIndex is not always 0 after a match or replace using a "global" regex is complete.) This should alert 0, demonstrating that the browsers you mentioned do update lastIndex: var x = /x/g; x.lastIndex = 1; "x123x5".match(x); alert(x.lastIndex); > or String#replace. > IE does set the lastIndex but only once, not during each internal > iteration of `Repeat, while lastMatch is true`, and for non-global > regexp's as well. > > According to spec I would expect: > > var s = '0x2x4x6x8'; > var p = /x/g; > s.replace(p, function() { alert(p.lastIndex) }); // A: alerts 2, then > 4, then 6, then 8 > alert(p.lastIndex); // B: alerts 0 because internal exec returned null > (which set lastIndex 0) triggering the end of the iteration; > > // IE7 > // A: alerts 0, then 0, then 0, then 0 > // B: alerts 8 > > // All others > // A: alerts 0, then 0, then 0, then 0 > // B: alerts 0 Opera 9.64 (and other versions I've previously tested this issue with) alerts A: 2, 4, 6, 8 and B: 0. Like you, this is my interpretation of correct handling according to the spec. Opera tends to follow the spec most closely for regex issues, in general. > This might be a compatibility issue to consider. Sure, but it's a decade old. Steve -------------------- Steven Levithan Baghdad, Iraq http://blog.stevenlevithan.com _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: String#replace String#match and regexp.lastIndexOn Jul 1, 2009, at 10:08 AM, Steve L. wrote:
> Opera 9.64 (and other versions I've previously tested this issue > with) alerts A: 2, 4, 6, 8 and B: 0. Like you, this is my > interpretation of correct handling according to the spec. Opera > tends to follow the spec most closely for regex issues, in general. This seems like a bug for other vendors than Opera to fix. Filed: https://bugzilla.mozilla.org/show_bug.cgi?id=501739 I suspect no one will mind the fix, and a few will welcome it. But we will have to try it out on real developers and users to be sure. /be _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: String#replace String#match and regexp.lastIndex@Steve - You are correct about Opera and about other browsers use of
String#match. I must have been using an invalid test at the time. Thanks for the additional info. @Brendan - Thanks for creating the bug report :D _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: String#replace String#match and regexp.lastIndexIt may be beneficial to clarify in the ES5 spec that searches should take
place and lastIndex should be updated based on a copy of the value of lastIndex made at the start of String#replace's processing. If you follow the dependency chain--where String#replace relies on the definition of String#match, which in turn relies on RegExp#exec--it looks to me like the spec requires this code to become an infinite loop: var str="0x2x3", a=["x","y","z"], i=0, re=/x/g; alert(str.replace(re, function(){ re.lastIndex = 0; return a[i++]; })); However, it is not an infinite loop in 5 out of 5 browsers. It should also be unambiguous that this would alert "0x2y3" (as it does in all the big browsers) and not "0y2z3". While we're discussing String#replace, is it too late to formally spec what $n and $nn in replacement strings should mean when n is greater than the number of capturing groups within the regex? ES 3 & 5-draft say this is implementation-defined. Firefox 3.5, IE 8, Safari 4, Chrome 2, Opera 9.64, and all other browsers I've tested with say that e.g. "test".replace(/(e)/, "$2") returns "t$2st". I rely on this behavior, and I may not be the only one. Steve -------------------- Steven Levithan Baghdad, Iraq http://blog.stevenlevithan.com _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: String#replace String#match and regexp.lastIndexIt may be beneficial to clarify in the ES5 spec that searches should take
place and lastIndex should be updated based on a copy of the value of lastIndex made at the start of String#replace's processing. If you follow the dependency chain--where String#replace relies on the definition of String#match, which in turn relies on RegExp#exec--it looks to me like the spec requires this code to become an infinite loop: var str="0x2x3", a=["x","y","z"], i=0, re=/x/g; alert(str.replace(re, function(){ re.lastIndex = 0; return a[i++]; })); However, it is not an infinite loop in 5 out of 5 browsers. It should also be unambiguous that this would alert "0x2y3" (as it does in all the big browsers) and not "0y2z3". While we're discussing String#replace, is it too late to formally spec what $n and $nn in replacement strings should mean when n is greater than the number of capturing groups within the regex? ES 3 & 5-draft say this is implementation-defined. Firefox 3.5, IE 8, Safari 4, Chrome 2, Opera 9.64, and all other browsers I've tested with say that e.g. "test".replace(/(e)/, "$2") returns "t$2st". I rely on this behavior, and I may not be the only one. Steve -------------------- Steven Levithan Baghdad, Iraq http://blog.stevenlevithan.com _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
| Free embeddable forum powered by Nabble | Forum Help |