« Bugzilla Issues Index

#1571 — look-ahead assertion followed by quantifier acceptable

As has been documented elsewhere (e.g. there is a mismatch between the ES5 spec and what browsers really do. This is another such difference.

/(?=a)*/.test('a') returns true on all main browsers, but it is a syntax error according to the spec (or at least, that is my reading). The browser behavior is in line with Perl. All browsers do report a syntax error for the related /^*/.test('a').

The spec has the following definition for Term:
Term :: Assertion
Term :: Atom
Term :: Atom Quantifier
Hence, the input "Assertion Quantifier" is invalid syntax.

The simplest, but ugly solution would be to extend Term:
Term :: (?= Disjunction ) Quantifier
Term :: (?! Disjunction ) Quantifier

Another solution could be to define look ahead assertions as Atoms. The presence of Note 2 and 3 to section (instead of being notes to section suggests that this may have been the case in some old draft version of the spec. Making look ahead assertions Atoms matches with the "web reality" semantics for this idiom, i.e. /(?=a)*/.test('b') returns true, /(?=a)+/.test('b') returns false.

Had a look at the ES3 spec and indeed in that version (?=) and (?!) are zero-width atoms, not assertions. The change is not highlighted in the ES3->ES5 changes sections, so the reasoning behind the change in the ES5 spec remains unclear to me.

This issue seems to have already been flagged by Luke Hoban in May 2011:

His strawman proposes extending the definition of Term, similar to my 'simple' solution.

This is the only record I can find of the motivation for the change

Unfortunately, the bug database that was being use at that time has been lost.

The changes first showed up in the Feb 23, 2009 ES5 draft

It's possible that that the change was not correctly motivated and should be rolled-back or that a different fix is need for the root problem.

It would probably make sense to open a more visible discussion of this on es-discuss.

Deferred to ES7