Lookarounds are zero-width assertions that match a string without consuming anything. ECMAScript has lookahead assertions that does this in forward direction, but the language is missing a way to do this backward which the lookbehind assertions provide. With lookbehind assertions, one can make sure that a pattern is or isn't preceded by another, e.g. matching a dollar amount without capturing the dollar sign.

See the proposal repository for background material and discussion.

Each `\u`

`u`

`u`

`\u`

The production

- Evaluate
Disjunction with +1 as its`direction`argument to obtain a Matcher`m`. - Return an internal closure that takes two arguments, a String
`str`and an integer`index`, and performs the following steps:- Assert:
`index`≤ the number of elements in`str`. - If
`Unicode`istrue , let`Input`be aList consisting of the sequence of code points of`str`interpreted as a UTF-16 encoded (6.1.4 ) Unicode string. Otherwise, let`Input`be aList consisting of the sequence of code units that are the elements of`str`.`Input`will be used throughout the algorithms in21.2.2 . Each element of`Input`is considered to be a character. - Let
`InputLength`be the number of characters contained in`Input`. This variable will be used throughout the algorithms in21.2.2 . - Let
`listIndex`be the index into`Input`of the character that was obtained from element`index`of`str`. - Let
`c`be a Continuation that always returns its State argument as a successful MatchResult. - Let
`cap`be aList of`NcapturingParens`undefined values, indexed 1 through`NcapturingParens`. - Let
`x`be the State (`listIndex`,`cap`). - Call
`m`(`x`,`c`) and return its result.

- Assert:

A Pattern evaluates (“compiles”) to an internal procedure value.

With argument `direction`.

The production

The production

- Evaluate
Alternative with argument`direction`to obtain a Matcher`m1`. - Evaluate
Disjunction with argument`direction`to obtain a Matcher`m2`. - Return an internal Matcher closure that takes two arguments, a State
`x`and a Continuation`c`, and performs the following steps when evaluated:- Call
`m1`(`x`,`c`) and let`r`be its result. - If
`r`is notfailure , return`r`. - Call
`m2`(`x`,`c`) and return its result.

- Call

The `|`

regular expression operator separates two alternatives. The pattern first tries to match the left `|`

produce

`/a|ab/.exec("abc")`

returns the result `"a"`

and not `"ab"`

. Moreover,

`/((a)|(ab))((c)|(bc))/.exec("abc")`

returns the array

`["abc", "a", "a", undefined, "bc", undefined, "bc"]`

and not

`["abc", "ab", undefined, "ab", "c", "c", undefined]`

The order in which the two alternatives are tried is independent of the value of `direction`.

With argument `direction`.

The production `x` and a Continuation `c`, and returns the result of calling `c`(`x`).

The production

- Evaluate
Alternative with argument`direction`to obtain a Matcher`m1`. - Evaluate
Term with argument`direction`to obtain a Matcher`m2`. - If
`direction`is equal to +1, then,- Return an internal Matcher closure that takes two arguments, a State
`x`and a Continuation`c`, and performs the following steps when evaluated:- Let
`d`be a Continuation that takes a State argument`y`and returns the result of calling`m2`(`y`,`c`). - Call
`m1`(`x`,`d`) and return its result.

- Let

- Return an internal Matcher closure that takes two arguments, a State
- Else,
`direction`is equal to -1.- Return an internal Matcher closure that takes two arguments, a State
`x`and a Continuation`c`, and performs the following steps when evaluated:- Let
`d`be a Continuation that takes a State argument`y`and returns the result of calling`m1`(`y`,`c`). - Call
`m2`(`x`,`d`) and return its result.

- Let

- Return an internal Matcher closure that takes two arguments, a State

Consecutive `Input`.
When `direction` is equal to +1, if the left

With argument `direction`.

The production `x` and a Continuation `c`, and performs the following steps when evaluated:

- Evaluate
Assertion to obtain an AssertionTester`t`. - Call
`t`(`x`) and let`r`be the resulting Boolean value. - If
`r`isfalse , returnfailure . - Call
`c`(`x`) and return its result.

The AssertionTester is independent of `direction`.

The production

- Return the Matcher that is the result of evaluating
Atom with argument`direction`.

The production

- Evaluate
Atom with argument`direction`to obtain a Matcher`m`. - Evaluate
Quantifier to obtain the three results: an integer`min`, an integer (or ∞)`max`, and Boolean`greedy`. - If
`max`is finite and less than`min`, throw aSyntaxError exception. - Let
`parenIndex`be the number of left capturing parentheses in the entire regular expression that occur to the left of this production expansion'sTerm . This is the total number of times the production is expanded prior to this production'sAtom :: ( Disjunction ) Term plus the total number of productions enclosing thisAtom :: ( Disjunction ) Term . - Let
`parenCount`be the number of left capturing parentheses in the expansion of this production'sAtom . This is the total number of productions enclosed by this production'sAtom :: ( Disjunction ) Atom . - Return an internal Matcher closure that takes two arguments, a State
`x`and a Continuation`c`, and performs the following steps when evaluated:- Call
RepeatMatcher (`m`,`min`,`max`,`greedy`,`x`,`c`,`parenIndex`,`parenCount`) and return its result.

- Call

The abstract operation RepeatMatcher takes eight parameters, a Matcher `m`, an integer `min`, an integer (or ∞) `max`, a Boolean `greedy`, a State `x`, a Continuation `c`, an integer `parenIndex`, and an integer `parenCount`, and performs the following steps:

- If
`max`is zero, return`c`(`x`). - Let
`d`be an internal Continuation closure that takes one State argument`y`and performs the following steps when evaluated:- If
`min`is zero and`y`'s`endIndex`is equal to`x`'s`endIndex`, returnfailure . - If
`min`is zero, let`min2`be zero; otherwise let`min2`be`min`-1. - If
`max`is ∞, let`max2`be ∞; otherwise let`max2`be`max`-1. - Call
RepeatMatcher (`m`,`min2`,`max2`,`greedy`,`y`,`c`,`parenIndex`,`parenCount`) and return its result.

- If
- Let
`cap`be a fresh copy of`x`'s`captures`List . - For each integer
`k`that satisfies`parenIndex`<`k`and`k`≤`parenIndex`+`parenCount`, set`cap`[`k`] toundefined . - Let
`e`be`x`'s`endIndex`. - Let
`xr`be the State (`e`,`cap`). - If
`min`is not zero, return`m`(`xr`,`d`). - If
`greedy`isfalse , then- Call
`c`(`x`) and let`z`be its result. - If
`z`is notfailure , return`z`. - Call
`m`(`xr`,`d`) and return its result.

- Call
- Call
`m`(`xr`,`d`) and let`z`be its result. - If
`z`is notfailure , return`z`. - Call
`c`(`x`) and return its result.

An

If the ^{th}) repetition of ^{st} repetition of ^{st} repetition of

Compare

`/a[a-z]{2,4}/.exec("abcdefghi")`

which returns `"abcde"`

with

`/a[a-z]{2,4}?/.exec("abcdefghi")`

which returns `"abc"`

.

Consider also

`/(aa|aabaac|ba|b|c)*/.exec("aabaac")`

which, by the choice point ordering above, returns the array

`["aaba", "ba"]`

and not any of:

```
["aabaac", "aabaac"]
["aabaac", "c"]
```

The above ordering of choice points can be used to write a regular expression that calculates the greatest common divisor of two numbers (represented in unary notation). The following example calculates the gcd of 10 and 15:

`"aaaaaaaaaa,aaaaaaaaaaaaaaa".replace(/^(a+)\1*,\1+$/,"$1")`

which returns the gcd in unary notation `"aaaaa"`

.

Step 4 of the RepeatMatcher clears

`/(z)((a+)?(b+)?(c))*/.exec("zaacbbbcac")`

which returns the array

`["zaacbbbcac", "z", "ac", "a", undefined, "c"]`

and not

`["zaacbbbcac", "z", "ac", "a", "bbb", "c"]`

because each iteration of the outermost `*`

clears all captured Strings contained in the quantified

Step 1 of the RepeatMatcher's `d` closure states that, once the minimum number of repetitions has been satisfied, any more expansions of

`/(a*)*/.exec("b")`

or the slightly more complicated:

`/(a*)b\1+/.exec("baaaac")`

which returns the array

`["b", ""]`

The production `x` and performs the following steps when evaluated:

- Let
`e`be`x`'s`endIndex`. - If
`e`is zero, returntrue . - If
`Multiline`isfalse , returnfalse . - If the character
`Input`[`e`-1] is one ofLineTerminator , returntrue . - Return
false .

Even when the `y`

flag is used with a pattern, `^`

always matches only at the beginning of `Input`, or (if `Multiline` is

The production `x` and performs the following steps when evaluated:

- Let
`e`be`x`'s`endIndex`. - If
`e`is equal to`InputLength`, returntrue . - If
`Multiline`isfalse , returnfalse . - If the character
`Input`[`e`] is one ofLineTerminator , returntrue . - Return
false .

The production `x` and performs the following steps when evaluated:

- Let
`e`be`x`'s`endIndex`. - Call
IsWordChar (`e`-1) and let`a`be the Boolean result. - Call
IsWordChar (`e`) and let`b`be the Boolean result. - If
`a`istrue and`b`isfalse , returntrue . - If
`a`isfalse and`b`istrue , returntrue . - Return
false .

The production `x` and performs the following steps when evaluated:

- Let
`e`be`x`'s`endIndex`. - Call
IsWordChar (`e`-1) and let`a`be the Boolean result. - Call
IsWordChar (`e`) and let`b`be the Boolean result. - If
`a`istrue and`b`isfalse , returnfalse . - If
`a`isfalse and`b`istrue , returnfalse . - Return
true .

The production

- Evaluate
Disjunction with +1 as its`direction`argument to obtain a Matcher`m`. - Return an internal Matcher closure that takes two arguments, a State
`x`and a Continuation`c`, and performs the following steps:- Let
`d`be a Continuation that always returns its State argument as a successful MatchResult. - Call
`m`(`x`,`d`) and let`r`be its result. - If
`r`isfailure , returnfailure . - Let
`y`be`r`'s State. - Let
`cap`be`y`'s`captures`List . - Let
`xe`be`x`'s`endIndex`. - Let
`z`be the State (`xe`,`cap`). - Call
`c`(`z`) and return its result.

- Let

The production

- Evaluate
Disjunction with +1 as its`direction`argument to obtain a Matcher`m`. - Return an internal Matcher closure that takes two arguments, a State
`x`and a Continuation`c`, and performs the following steps:- Let
`d`be a Continuation that always returns its State argument as a successful MatchResult. - Call
`m`(`x`,`d`) and let`r`be its result. - If
`r`is notfailure , returnfailure . - Call
`c`(`x`) and return its result.

- Let

The production

- Evaluate
Disjunction with -1 as its`direction`argument to obtain a Matcher`m`. - Return an internal Matcher closure that takes two arguments, a State
`x`and a Continuation`c`, and performs the following steps:- Let
`d`be a Continuation that always returns its State argument as a successful MatchResult. - Call
`m`(`x`,`d`) and let`r`be its result. - If
`r`isfailure , returnfailure . - Let
`y`be`r`'s State. - Let
`cap`be`y`'s`captures`List . - Let
`xe`be`x`'s`endIndex`. - Let
`z`be the State (`xe`,`cap`). - Call
`c`(`z`) and return its result.

- Let

The production

- Evaluate
Disjunction with -1 as its`direction`argument to obtain a Matcher`m`. - Return an internal Matcher closure that takes two arguments, a State
`x`and a Continuation`c`, and performs the following steps:- Let
`d`be a Continuation that always returns its State argument as a successful MatchResult. - Call
`m`(`x`,`d`) and let`r`be its result. - If
`r`is notfailure , returnfailure . - Call
`c`(`x`) and return its result.

- Let

The abstract operation WordCharacters performs the following steps:

- Let
`A`be a set of characters containing the sixty-three characters:`a`

`b`

`c`

`d`

`e`

`f`

`g`

`h`

`i`

`j`

`k`

`l`

`m`

`n`

`o`

`p`

`q`

`r`

`s`

`t`

`u`

`v`

`w`

`x`

`y`

`z`

`A`

`B`

`C`

`D`

`E`

`F`

`G`

`H`

`I`

`J`

`K`

`L`

`M`

`N`

`O`

`P`

`Q`

`R`

`S`

`T`

`U`

`V`

`W`

`X`

`Y`

`Z`

`0`

`1`

`2`

`3`

`4`

`5`

`6`

`7`

`8`

`9`

`_`

- Let
`U`be an empty set. - For each character
`c`not in set`A`whereCanonicalize (`c`) is in`A`, add`c`to`U`. - Assert: Unless
`Unicode`and`IgnoreCase`are bothtrue ,`U`is empty. - Add the characters in set
`U`to set`A`. - Return
`A`.

The abstract operation IsWordChar takes an integer parameter `e` and performs the following steps:

- If
`e`is -1 or`e`is`InputLength`, returnfalse . - Let
`c`be the character`Input`[`e`]. - Let
`wordChars`be the result of !WordCharacters (). - If
`c`is in`wordChars`, returntrue . - Return
false .

With argument `direction`.

The production

- Let
`ch`be the character matched byPatternCharacter . - Let
`A`be a one-element CharSet containing the character`ch`. - Call
CharacterSetMatcher (`A`,false ,`direction`) and return its Matcher result.

The production

- Let
`A`be the set of all characters exceptLineTerminator . - Call
CharacterSetMatcher (`A`,false ,`direction`) and return its Matcher result.

The production

- Return the Matcher that is the result of evaluating
AtomEscape with argument`direction`.

The production

- Evaluate
CharacterClass to obtain a CharSet`A`and a Boolean`invert`. - Call
CharacterSetMatcher (`A`,`invert`,`direction`) and return its Matcher result.

The production

- Evaluate
Disjunction with argument`direction`to obtain a Matcher`m`. - Let
`parenIndex`be the number of left capturing parentheses in the entire regular expression that occur to the left of this production expansion's initial left parenthesis. This is the total number of times the production is expanded prior to this production'sAtom :: ( Disjunction ) Atom plus the total number of productions enclosing thisAtom :: ( Disjunction ) Atom . - Return an internal Matcher closure that takes two arguments, a State
`x`and a Continuation`c`, and performs the following steps:- Let
`d`be an internal Continuation closure that takes one State argument`y`and performs the following steps:- Let
`cap`be a fresh copy of`y`'s`captures`List . - Let
`xe`be`x`'s`endIndex`. - Let
`ye`be`y`'s`endIndex`. - If
`direction`is equal +1, then- Let
`s`be a freshList whose characters are the characters of`Input`at indices`xe`(inclusive) through`ye`(exclusive).

- Let
- Else,
`direction`is equal to -1.- Let
`s`be a freshList whose characters are the characters of`Input`at indices`ye`(inclusive) through`xe`(exclusive).

- Let
- Set
`cap`[`parenIndex`+1] to`s`. - Let
`z`be the State (`ye`,`cap`). - Call
`c`(`z`) and return its result.

- Let
- Call
`m`(`x`,`d`) and return its result.

- Let

The production

- Return the Matcher that is the result of evaluating
Disjunction with argument`direction`.

With argument `direction`.

The abstract operation CharacterSetMatcher takes ~~two~~three arguments, a CharSet `A`, a Boolean flag `invert` and an integer `direction`, and performs the following steps:

- Return an internal Matcher closure that takes two arguments, a State
`x`and a Continuation`c`, and performs the following steps when evaluated:- Let
`e`be`x`'s`endIndex`. - Let
`f`be`e`+`direction`. ~~If~~`e`is`InputLength`, returnfailure .- If
`f`< 0 or`f`>`InputLength`, returnfailure . ~~Let~~`ch`be the character`Input`[`e`].- Let
`index`bemin (`e`,`f`). - Let
`ch`be the character`Input`[`index`].. - Let
`cc`beCanonicalize (`ch`). - If
`invert`isfalse , then- If there does not exist a member
`a`of set`A`such thatCanonicalize (`a`) is`cc`, returnfailure .

- If there does not exist a member
- Else
`invert`istrue ,- If there exists a member
`a`of set`A`such thatCanonicalize (`a`) is`cc`, returnfailure .

- If there exists a member
- Let
`cap`be`x`'s`captures`List . ~~Let~~`y`be the State (`e`+1,`cap`).- Let
`y`be the State (`f`,`cap`). - Call
`c`(`y`) and return its result.

- Let

The abstract operation Canonicalize takes a character parameter `ch` and performs the following steps:

- If
`IgnoreCase`isfalse , return`ch`. - If
`Unicode`istrue , then- If the file CaseFolding.txt of the Unicode Character Database provides a simple or common case folding mapping for
`ch`, return the result of applying that mapping to`ch`. - Else, return
`ch`.

- If the file CaseFolding.txt of the Unicode Character Database provides a simple or common case folding mapping for
- Else,
- Assert:
`ch`is a UTF-16 code unit. - Let
`s`be the ECMAScript String value consisting of the single code unit`ch`. - Let
`u`be the same result produced as if by performing the algorithm for`String.prototype.toUpperCase`

using`s`as thethis value. - Assert:
`u`is a String value. - If
`u`does not consist of a single code unit, return`ch`. - Let
`cu`be`u`'s single code unit element. - If
`ch`'s code unit value ≥ 128 and`cu`'s code unit value < 128, return`ch`. - Return
`cu`.

- Assert:

Parentheses of the form `(`

`)`

serve both to group the components of the `\`

followed by a nonzero decimal number), referenced in a replace String, or returned as part of an array from the regular expression matching internal procedure. To inhibit the capturing behaviour of parentheses, use the form `(?:`

`)`

instead.

The form `(?=`

`)`

specifies a zero-width positive lookahead. In order for it to succeed, the pattern inside `(?=`

form (this unusual behaviour is inherited from Perl). This only matters when the

For example,

`/(?=(a+))/.exec("baaabac")`

matches the empty String immediately after the first `b`

and therefore returns the array:

`["", "aaa"]`

To illustrate the lack of backtracking into the lookahead, consider:

`/(?=(a+))a*b\1/.exec("baaabac")`

This expression returns

`["aba", "a"]`

and not:

`["aaaba", "a"]`

The form `(?!`

`)`

specifies a zero-width negative lookahead. In order for it to succeed, the pattern inside

`/(.*?)a(?!(a+)b\2c)\2(.*)/.exec("baaabaac")`

looks for an `a`

not immediately followed by some positive number n of `a`

's, a `b`

, another n `a`

's (specified by the first `\2`

) and a `c`

. The second `\2`

is outside the negative lookahead, so it matches against

`["baaabaac", "ba", undefined, "abaac"]`

In case-insignificant matches when `Unicode` is `"ß"`

(U+00DF) to `"SS"`

. It may however map a code point outside the Basic Latin range to a character within, for example, `"ſ"`

(U+017F) to `"s"`

. Such characters are not mapped if `Unicode` is `/[a-z]/i`

, but they will match `/[a-z]/ui`

.

With argument `direction`.

The production

- Evaluate
DecimalEscape to obtain an integer`n`. - If
`n`>`NcapturingParens`, throw aSyntaxError exception. - Return an internal Matcher closure that takes two arguments, a State
`x`and a Continuation`c`, and performs the following steps:- Let
`cap`be`x`'s`captures`List . - Let
`s`be`cap`[`n`]. - If
`s`isundefined , return`c`(`x`). - Let
`e`be`x`'s`endIndex`. - Let
`len`be`s`'s length. ~~Let~~`f`be`e`+`len`.- Let
`f`be`e`+`direction`×`len`. - If
`f`< 0 or`f`>`InputLength`, returnfailure . - Let
`g`bemin (`e`,`f`). - If there exists an integer
`i`between 0 (inclusive) and`len`(exclusive) such thatCanonicalize (`s`[`i`]) is not the same character value asCanonicalize (`Input`[`e`+`i``g`+`i`]), returnfailure . - Let
`y`be the State (`f`,`cap`). - Call
`c`(`y`) and return its result.

- Let

The production

- Evaluate
CharacterEscape to obtain a character`ch`. - Let
`A`be a one-element CharSet containing the character`ch`. - Call
CharacterSetMatcher (`A`,false ,`direction`) and return its Matcher result.

The production

- Evaluate
CharacterClassEscape to obtain a CharSet`A`. - Call
CharacterSetMatcher (`A`,false ,`direction`) and return its Matcher result.

An escape sequence of the form `\`

followed by a nonzero decimal number `n` matches the result of the `n`th set of capturing parentheses (`n` capturing parentheses. If the regular expression has `n` or more capturing parentheses but the `n`th one is