Спецификация ECMAScript 5.1 с аннотациями

Поделиться

15.10 Объекты RegExp (регулярное выражение) #

Объект RegExp содержит регулярное выражение и связанные с ним флаги.

ПРИМЕЧАНИЕ Вид и функциональные возможности регулярных выражений созданы по образцу средств регулярных выражений в языке программирования Perl 5.

15.10.1 Шаблоны #

Конструктор RegExp применяет к входной строке-шаблону следующую грамматику. Если грамматика не может интерпретировать строку как развёртывание шаблона Pattern, происходит ошибка.

Синтаксис

Pattern ::

Disjunction

Disjunction ::

Alternative
Alternative
| Disjunction

Alternative ::

[пусто]
Alternative Term

Term ::

Assertion
Atom
Atom Quantifier

Assertion ::

^
$
\ b
\ B
(
? = Disjunction )
( ? ! Disjunction )

Quantifier ::

QuantifierPrefix
QuantifierPrefix
?

QuantifierPrefix ::

*
+

?
{ DecimalDigits }
{ DecimalDigits, }
{ DecimalDigits, DecimalDigits }

Atom ::

PatternCharacter
.
\ AtomEscape
CharacterClass

(
Disjunction )
( ? : Disjunction )

PatternCharacter ::SourceCharacter но не один из следующих:

^ $ \ . * + ? ( ) [ ] { } |

AtomEscape ::

DecimalEscape
CharacterEscape
CharacterClassEscape

CharacterEscape ::

ControlEscape
c ControlLetter
HexEscapeSequence
UnicodeEscapeSequence
IdentityEscape

SingleEscapeCharacter :: один из

f n r t v

ControlLetter :: один из

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

IdentityEscape ::

SourceCharacter но не IdentifierPart
<ZWJ>
<ZWNJ>

DecimalEscape ::

DecimalIntegerLiteral [lookahead DecimalDigit]

CharacterClassEscape :: один из

d D s S w W

CharacterClass ::

[[lookahead {^}] ClassRanges]
[ ^ ClassRanges]

ClassRanges ::

[пусто]
NonemptyClassRanges

NonemptyClassRanges ::

ClassAtom
ClassAtom NonemptyClassRangesNoDash
ClassAtom
- ClassAtom ClassRanges

NonemptyClassRangesNoDash ::

ClassAtom
ClassAtomNoDash NonemptyClassRangesNoDash
ClassAtomNoDash
- ClassAtom ClassRanges

ClassAtom ::

-
ClassAtomNoDash

ClassAtomNoDash ::

SourceCharacter но не один из \ или ] или -
\ClassEscape

ClassEscape ::

DecimalEscape
b
CharacterEscape

CharacterClassEscape

15.10.2 Семантика шаблонов #

Шаблон регулярного выражения преобразуется во внутреннюю процедуру с помощью описанных ниже алгоритмов. Реализации рекомендуется использовать более эффективные алгоритмы, чем представленные ниже, если их результат будет таким же. Внутренняя процедура используется в качестве значения внутреннего свойства [[Match]] объекта RegExp.

15.10.2.1 Обозначения #

В приведённых ниже описаниях используются следующие переменные:

Кроме того, в приведённых ниже описаниях используются следующие внутренние структуры данных:

15.10.2.2 Шаблон (Pattern) #

Для вычисления Pattern:: Disjunction выполняются следующие шаги:

  1. Вычислить Disjunction , получив в результате Matcher m.

  2. Вернуть внутреннее замкнутое выражение, принимающее два аргумента – строку str и целое число index, и выполняющее следующие действия:

  1. Пусть Input будет заданной строкой str. Эта переменная будет использоваться во всех алгоритмах в пункте 15.10.2.

  2. Пусть InputLength будет длиной для Input. Эта переменная будет использоваться во всех алгоритмах в пункте 15.10.2.

  3. Пусть c будет Continuation, которое всегда возвращает свой аргумент State в качестве успешного результата совпадений MatchResult.

  4. Пусть cap будет внутренним массивом из значений undefined в количестве NcapturingParens с индексом от 1 до NcapturingParens.

  5. Пусть x будет State (index, cap).

  6. Вызвать m(x, c) и вернуть результат.

ПРИМЕЧАНИЕ Шаблон вычисляет ("компилирует") значение внутренней процедуры. Затем RegExp.prototype.exec может применить эту процедуру к строке и к смещению в этой строке, чтобы определить, будет ли найдено соответствие для шаблона, если начать именно с места смещения, и, если да – то какими будут значения захватывающих скобок. Алгоритмы в пункте 15.10.2 рассчитаны на то, чтобы при компиляции шаблона было возможно сгенерировать исключение SyntaxError. С другой стороны, после того, как компиляция шаблона была успешно произведена, применение результирующей внутренней процедуры для нахождения соответствия в строке не может сгенерировать исключения (кроме исключений, заданных средой, которые могут возникнуть где угодно – например, исключительная ситуация из-за нехватки памяти).

15.10.2.3 Дизъюнкция (Disjunction) #

Для вычисления Disjunction :: Alternative производится вычисление Alternative для получения Matcher, а затем возврат этого Matcher.

Для вычисления Disjunction :: Alternative | Disjunction выполняются следующие шаги:

  1. Вычислить Alternative для получения Matcher m1.

  2. Вычислить Disjunction для получения Matcher m2.

  3. Вернуть внутреннее замкнутое выражение Matcher, принимающее два аргумента – State x и Continuation c, и выполнить следующие шаги:

        1. Вызвать m1(x, c), и пусть r будет его результатом.

        2. Если r не равно failure, вернуть r.

        3. Вызвать m2(x, c) и вернуть результат.

ПРИМЕЧАНИЕ Оператор регулярного выражения | разделяет две альтернативы. Сначала шаблон пытается найти совпадение с левой альтернативой Alternative (за которой следует продолжение регулярного выражения). Если это ему не удаётся, он пытается найти совпадение с правой дизъюнкцией Disjunction (за которой следует продолжение регулярного выражения). Если точки выбора альтернативы есть и в левой Альтернативе, и в правой Дизъюнкции, и в продолжении, то перед тем, как переходить к следующему варианту выбора в левой Альтернативе, необходимо попробовать все варианты выбора в продолжении. Если все варианты выбора в левой Альтернативе исчерпаны, то вместо левой Альтернативы необходимо проверить правую Дизъюнкцию. Если в результате использования оператора | пропускаются захватывающие скобки внутри части шаблона, то вместо строк получается значение undefined. Так, например,

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

возвращает результат "a", а не "ab". Кроме того,

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

возвращает массив

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

а не

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

15.10.2.4 Альтернатива (Alternative) #

Для вычисления Alternative :: [пусто] производится возврат Matcher, принимающего два аргумента – State x и Continuation c, и возвращающего результат вызова c(x).

Для вычисления Alternative :: Alternative Term выполняются следующие шаги:

  1. Вычислить Alternative для получения Matcher m1.

  2. Вычислить Term для получения Matcher m2.

  3. Вернуть внутреннее замкнутое выражение Matcher, принимающее два аргумента – State x и Continuation c, и выполняющее следующие шаги:

        1. Создать Continuation d, принимающее аргумент State y и возвращающее результат вызова m2(y, c).

        2. Вызвать m1(x, d) и вернуть результат.

ПРИМЕЧАНИЕ Последовательно следующие друг за другом Terms пытаются одновременно соответствовать последовательным частям входной строки. Если точки выбора есть и в левом Alternative, и в правом элементе Term, и в продолжении регулярного выражения, то перед тем, как переходить к следующему варианту выбора в правом Term, необходимо попробовать все варианты выбора в продолжении, и прежде чем перейти к следующему варианту выбора в левом Alternative, необходимо проверить все варианты выбора в правом Term.

15.10.2.5 Элемент (Term) #

Для вычисления Term ::Assertion вернуть внутреннее замкнутое выражение Matcher, принимающее два аргумента – State x и Continuation c, и выполняющее следующие шаги:

  1. Вычислить Assertion для получения AssertionTester t.

  2. Вызвать t(x), и пусть r будет полученным булевым значением.

  3. Если r равно false, вернуть failure.

  4. Вызвать c(x) и вернуть результат.

Для вычисления Term ::Atom производится вычисление Atom для получения Matcher, а затем возврат этого Matcher.

Для вычисления Term ::Atom Quantifier выполняются следующие шаги:

  1. Вычислить Atom для получения Matcher m.

  2. Вычислить Quantifier и получить три результата: целое min, целое (или ) max, и булево greedy.

  3. Если max – конечное число, меньшее чем min, сгенерировать исключение SyntaxError.

  4. Пусть parenIndex будет количеством открывающих захватывающих скобок во всём регулярном выражении, которые находятся слева от элемента Term этого правила. Оно равно общему количеству раз, когда правило Atom :: (Disjunction ) развёртывалось до элемента Term этого правила, плюс общее количество раз, когда этот элемент Term вложен в правило Atom :: (Disjunction ).

  5. Пусть parenCount будет количеством открывающих захватывающих скобок в развёртывании атома Atom этого правила. Оно равно общему количеству раз, когда правило Atom :: (Disjunction ) вложено в атом Atom этого правила.

  6. Вернуть внутреннее замкнутое выражение Matcher, принимающее два аргумента – State x и Continuation c, и выполнить следующие шаги:

        1. Вызвать RepeatMatcher(m, min, max, greedy, x, c, parenIndex, parenCount) и вернуть результат.

Абстрактная операция RepeatMatcher принимает восемь параметров – Matcher m, целое min, целое (или ) max, булево greedy, State x, Continuation c, целое parenIndex, и целое parenCount, и выполняет следующие действия:

  1. Если max равно нулю, то вызвать c(x) и вернуть результат.

  2. Создать внутреннее замкнутое выражение Continuation d, принимающее один аргумент State y, и выполняющее следующие действия:

        1. Если min равно нулю, а endIndex для y равно endIndex для x, вернуть failure.

        2. Если min равно нулю, пусть min2 будет ноль; в противном случае пусть min2 будет min–1.

        3. Если max равно , пусть max2 будет ; в противном случае пусть max2 будет max–1.

        4. Вызвать RepeatMatcher(m, min2, max2, greedy, y, c, parenIndex, parenCount) и вернуть результат.

  3. Пусть cap будет новой копией внутреннего массива captures для x.

  4. Для каждого целого числа k, удовлетворяющего условиям parenIndex < k и k parenIndex+parenCount, установить значение cap[k] равное undefined.

  5. Пусть e будет endIndex для x.

  6. Пусть xr будет State (e, cap).

  7. Если min не равно нулю, вызвать m(xr, d) и вернуть результат.

  8. Если greedy равно false, то

    1. Вызвать c(x), и пусть z будет результатом.

    2. Если z не равно failure, вернуть z.

    3. Вызвать m(xr, d) и вернуть результат.

  9. Вызвать m(xr, d), и пусть z будет результатом.

  10. Если z не равно failure, вернуть z.

  11. Вызвать c(x) и вернуть результат.

ПРИМЕЧАНИЕ Quantifier указывает, сколько раз за атомом Atom следует Quantifier. Квантификатор Quantifier может быть "нежадным" non-greedy – в этом случае шаблон Atom повторяется наименьшее возможное количество раз, при котором он совпадает с продолжением регулярного выражения. Либо он может быть "жадным" greedy, и в этом случае он повторяется наибольшее возможное количество раз, при котором он совпадает с продолжением. Повторяется шаблон Atom, а не входная строка, с которой он совпадает, поэтому различные повторения Atom могут совпадать с различными входными подстроками.

ПРИМЕЧАНИЕ 2 Если точки выбора альтернативы есть и у Atom, и у продолжения регулярного выражения, то сначала поиск совпадений производится в Atom в течение наиболее возможного количества раз (или наименее возможного количества раз, если квантификатор "нежадный"). Прежде чем переходить к следующему варианту выбора в последнем повторении Atom, необходимо проверить все варианты выбора в продолжении регулярного выражения. Необходимо проверить все варианты выбора последнего (n-ного) повторения Atom, прежде чем переходить к следующему варианту выбора в следующем повторении Atom (номер n–1). В этот момент может оказаться, что теперь доступно большее или меньшее количество повторений Atom. Тогда необходимо исчерпать все эти повторения (опять начиная либо с наименее возможного, либо с наиболее возможного количества раз), прежде чем переходить к следующему варианту выбора в повторении Atom номер n-1, и так далее.

Сравните

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

где возвращается "abcde", с

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

где возвращается "abc".

Также обратите внимание на

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

которое, с учётом указанного выше порядка точки выбора возвращает массив

["aaba", "ba"]

а не один из нижеперечисленных массивов:

["aabaac", "aabaac"]

["aabaac", "c"]

Вышеуказанный порядок точки выбора может быть использован для написания регулярного выражения, вычисляющего наибольший общий делитель из двух чисел (в унарной записи). В следующем примере вычисляется наибольший общий делитель для 10 и 15:

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

возвращающий наибольший общий делитель в унарной записи "aaaaa".

ПРИМЕЧАЕНИЕ 3 Каждый раз при повторении Atom выполнение шага 4 из RepeatMatcher очищает captures в элементе Atom. Можно увидеть его поведение в следующем регулярном выражении:

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

которое возвращает массив

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

а не

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

потому что каждая итерация самого крайнего * очищает все захваченные строки, содержащиеся в квантифицированном Atom, который в этом случае включает в себя захватываемые строки номер 2, 3 и 4.

ПРИМЕЧАНИЕ 4 Шаг 1 замкнутого выражения d из RepeatMatcher утверждает, что как только было получено минимальное количество повторений, для дальнейших повторений больше не рассматриваются развёртывания Atom, совпадающие с пустой строкой. Это не позволяет механизму регулярного выражения оказаться в бесконечном цикле с такими шаблонами, как:

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

или с чуть более сложным:

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

который возвращает массив

["b", ""]

15.10.2.6 Утверждение (Assertion) #

Для вычисления Assertion :: ^ возвращается внутреннее замкнутое выражение AssertionTester, принимающее аргумент x для State, и выполняются следующие действия:

  1. Пусть e будет endIndex для x.

  2. Если e равно нулю, вернуть true.

  3. Если Multiline равно false, вернуть false.

  4. Если символ Input[e–1] является одним из LineTerminator, вернуть true.

  5. Вернуть false.

Для вычисления Assertion :: $ возвращается внутреннее замкнутое выражение AssertionTester, принимающее аргумент x для State, и выполняются следующие действия:

  1. Пусть e будет endIndex для x.

  2. Если e равно InputLength, вернуть true.

  3. Если multiline равно false, вернуть false.

  4. Если символ Input[e] является одним из LineTerminator, вернуть true.

  5. Вернуть false.

Для вычисления Assertion :: \ b возвращается внутреннее замкнутое выражение AssertionTester, принимающее аргумент x для State, и выполняются следующие действия:

  1. Пусть e будет endIndex для x.

  2. Вызвать IsWordChar(e–1), и пусть a будет булевым результатом.

  3. Вызвать IsWordChar(e) и пусть b будет булевым результатом.

  4. Если a равно true и b равно false, вернуть true.

  5. Если a равно false и b равно true, вернуть true.

  6. Вернуть false.

Для вычисления Assertion :: \ B возвращается внутреннее замкнутое выражение AssertionTester, принимающее аргумент x для State, и выполняются следующие действия:

  1. Пусть e будет endIndex для x.

  2. Вызвать IsWordChar(e–1), и пусть a будет булевым результатом.

  3. Вызвать IsWordChar(e) и пусть b будет булевым результатом.

  4. Если a равно true, а b равно false, вернуть false.

  5. Если a равно false, а b равно true, вернуть false.

  6. Вернуть true.

Для вычисления Assertion :: ( ? = Disjunction) выполняются следующие шаги:

  1. Вычислить Disjunction для получения Matcher m.

  2. Вернуть внутреннее замкнутое выражение Matcher, принимающее два аргумента – State x и Continuation c, и выполнить следующие шаги:

        1. Пусть d будет Continuation, которое всегда возвращает свой аргумент State в качестве успешного результата совпадений MatchResult.

        2. Вызвать m(x, d) и пусть r будет результатом.

        3. Если r равно failure, вернуть failure.

        4. Пусть y будет State для r.

        5. Пусть cap будет внутренним массивом captures для y.

        6. Пусть xe будет endIndex для x.

        7. Пусть z будет State (xe, cap).

        8. Вызвать c(z) и вернуть результат.

Для вычисления Assertion ::( ? ! Disjunction) выполняются следующие шаги:

  1. Вычислить Disjunction для получения Matcher m.

  2. Вернуть внутреннее замкнутое выражение Matcher, принимающее два аргумента – State x и Continuation c, и выполнить следующие шаги:

        1. Пусть d будет Continuation, которое всегда возвращает свой аргумент State в качестве успешного результата совпадений MatchResult.

        2. Вызвать m(x, d) и пусть r будет результатом.

        3. Если r не равно failure, вернуть failure.

        4. Вызвать c(x) и вернуть результат.

Абстрактная операция IsWordChar принимает целочисленный параметр e и производит следующие действия:

  1. Если e == –1 или e == InputLength, вернуть false.

  2. Пусть c будет символом Input[e].

  3. Если c является одним из ниже перечисленных шестидесяти трёх символов, вернуть true.

    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

    _

  4. Вернуть false.

15.10.2.7 Квантификатор (Quantifier) #

Для вычисления Quantifier :: QuantifierPrefix выполняются следующие шаги:

  1. Вычислить QuantifierPrefix и получить два результата: целое min и целое (или ) max.

  2. Вернуть три результата min , max, и true.

Для вычисления Quantifier :: QuantifierPrefix? выполняются следующие шаги:

  1. Вычислить QuantifierPrefix и получить два результата: целое min и целое (или ) max.

  2. Вернуть три результата: min , max, и false.

Для вычисления QuantifierPrefix :: * возвращается два результата: 0 и .

Для вычисления QuantifierPrefix :: + возвращается два результата: 1 и .

Для вычисления QuantifierPrefix :: ? возвращается два результата: 0 и 1.

Для вычисления QuantifierPrefix :: { DecimalDigits} выполняются следующие шаги:

  1. Пусть i будет MV для DecimalDigits (см. 7.8.3).

  2. Вернуть два результата: i и i. (Return the two results i and i.)

Для вычисления QuantifierPrefix :: { DecimalDigits, } выполняются следующие шаги:

  1. Пусть i будет MV для DecimalDigits.

  2. Вернуть два результата: i и .

Для вычисления QuantifierPrefix :: { DecimalDigits, DecimalDigits} выполняются следующие шаги:

  1. Пусть i будет MV для первого DecimalDigits.

  2. Пусть j будет MV для второго DecimalDigits.

  3. Вернуть два результата: i и j.

15.10.2.8 Атом (Atom) #

Для вычисления Atom ::PatternCharacter выполняются следующие шаги:

  1. Пусть ch будет символом, представленным PatternCharacter.

  2. Пусть A будет одноэлементным CharSet, содержащим символ ch.

  3. Вызвать CharacterSetMatcher(A, false) и вернуть результат Matcher.

Для вычисления Atom ::. выполняются следующие шаги:

  1. Пусть A будет набором всех символов, кроме LineTerminator.

  2. Вызвать CharacterSetMatcher(A, false) и вернуть результат Matcher.

Для вычисления Atom ::\ AtomEscape производится вычисление AtomEscape для получения Matcher, а затем возврат этого Matcher.

Для вычисления Atom ::CharacterClass выполняются следующие шаги:

  1. Вычислить CharacterClass, чтобы получить CharSet A и булево invert.

  2. Вызвать CharacterSetMatcher(A, invert) и вернуть результат Matcher.

Для вычисления Atom ::( Disjunction) выполняются следующие шаги:

  1. Вычислить Disjunction для получения Matcher m.

  2. Пусть parenIndex будет количеством открывающих захватывающих скобок во всём регулярном выражении, которые находятся слева от начальной левой скобки этого правила. Оно равно общему количеству раз, когда правило Atom :: (Disjunction ) развёртывалось до Atom этого правила, плюс общее количество раз, когда этот Atom вложен в правило Atom :: (Disjunction ).

  3. Вернуть внутреннее замкнутое выражение Matcher, принимающее два аргумента – State x и Continuation c, и выполняющее следующие шаги:

        1. Создать внутреннее замкнутое выражение Continuation d, принимающее один аргумент State y, и выполняющее следующие шаги:

              1. Пусть cap будет новой копией внутреннего массива captures для y.

              2. Пусть xe будет endIndex для x.

              3. Пусть ye будет endIndex для y.

              4. Пусть s будет новой строкой, символами которой являются символы Input в позициях с xe (включительно) по ye (не включительно).

              5. Установить cap[parenIndex+1] в значение s.

              6. Пусть z будет State (ye, cap).

              7. Вызвать c(z) и вернуть результат.

        2. Вызвать m(x, d) и вернуть результат.

Для вычисления Atom ::( ? : Disjunction производится вычисление Disjunction для получения Matcher, а затем возврат этого Matcher.

Абстрактная операция CharacterSetMatcher принимает два аргумента – CharSet A и булев флаг invert, и выполняет следующие действия:

  1. Вернуть внутреннее замкнутое выражение Matcher, принимающее два аргумента – State x и Continuation c, и выполнить следующие шаги:

    1. Пусть e будет endIndex для x.

    2. Если e == InputLength, вернуть failure.

    3. Пусть ch будет символом Input[e].

    4. Пусть cc будет результатом Canonicalize(ch).

    5. Если invert равно false, вернуть

      1. Если не существует такого элемента a в наборе A, чтобы Canonicalize(a) == cc, вернуть failure.

    6. Иначе invert равно true.

      1. Если существует такой элемент a в наборе A, чтобы Canonicalize(a) == cc, вернуть failure.

    7. Пусть cap будет внутренним массивом captures для x.

    8. Пусть y будет State (e+1, cap).

    9. Вызвать c(y) и вернуть результат.

Абстрактная операция Canonicalize принимает символьный параметр ch и выполняет следующие шаги:

  1. Если IgnoreCase равно false, вернуть ch.

  2. Пусть u будет преобразованным в верхний регистр ch, как если бы посредством вызова стандартного встроенного метода String.prototype.toUpperCase для состоящей из одного символа строки ch.

  3. Если u состоит не из одного символа, вернуть ch.

  4. Пусть cu будет символом для u.

  5. Если кодовое значение символа ch больше или равно десятичному 128, и кодовое значение символа cu меньше десятичного 128, вернуть ch.

  6. Вернуть cu.

ПРИМЕЧАНИЕ 1 Скобки формата ( Disjunction) служат как для группировки компонентов шаблона Disjunction, так и для сохранения результатов поиска совпадений. Этот результат либо может быть использован в обратной ссылке (символ \, за которым следует ненулевое десятичное число), на которую ссылается заменяющая строка, либо возвращён как часть массива из регулярного выражения, совпадающего с внутренней процедурой. Для запрета захватывающего поведения скобок используется формат (?: Disjunction).

ПРИМЕЧАНИЕ 2 Формат (?= Disjunction) означает положительный предпросмотр нулевой ширины. Чтобы он увенчался успехом, шаблон внутри Disjunction должен совпадать в текущей позиции, но текущая позиция не перемещается вперёд, прежде чем она совпадёт с продолжением. Если Disjunction может иметь несколько совпадений в текущей позиции, проверяется только первое из них. В отличие от других операторов регулярного выражения, здесь отсутствует поиск с возвратами в формат (?= (это необычное поведение унаследовано из языка Perl). Это имеет значение только в том случае, если Disjunction содержит захватывающие скобки, а продолжение шаблона содержит обратные ссылки на эти захватывающие скобки.

Например,

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

совпадает с пустой строкой сразу же после первого b, и поэтому возвращает массив:

["", "aaa"]

Чтобы проиллюстрировать отсутствие поиска с возвратами в предпросмотре, рассмотрим следующее выражение:

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

Это выражение возвращает

["aba", "a"]

а не

["aaaba", "a"]

ПРИМЕЧАНИЕ 3 Формат (?! Disjunction) означает отрицательный предпросмотр нулевой ширины. Чтобы он был успешным, шаблон в дизъюнкции Disjunction не должен содержать совпадения в текущей позиции. Текущая позиция не перемещается вперёд до поиска соответствия в продолжении. Disjunction может содержать захватывающие скобки, но обратные ссылки на них имеют смысл только из самого Disjunction. Обратные ссылки на эти захватывающие скобки из любого другого места в шаблоне всегда возвращают undefined, поскольку, чтобы для этого шаблона нашлось соответствие, отрицательный предпросмотр должен оказаться неуспешным. Например,

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

ищет a, сразу же за которой не идёт последовательность из некоторого положительного количества n символов a, символа b, ещё одного количества n символов a (заданного первой ссылкой \2) и символа c. Вторая последовательность \2 находится за пределами отрицательного предпросмотра, поэтому она ищет совпадение с undefined и поэтому всегда оказывается находит. Всё выражение возвращает массив:

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

При поиске совпадений, где регистр не имеет значения, все символы непосредственно перед сравнением явным образом преобразуются в верхнему регистру. Однако, если при преобразовании символа в верхний регистр он разрастётся до более чем одного символа (например, как в случае с символом "ß" (\u00DF), который преобразуется в "SS"), то этот символ остаётся без изменений. Кроме того, символ также остаётся без изменений, если он не является символом ASCII, но в результате его преобразования в верхний регистр он превратился бы в символ ASCII. Это позволяет избежать того, чтобы такие символы Юникода, как \u0131 и \u017F не совпадали с регулярным выражением /[a z]/i, которые должны соответствовать только буквам ASCII. Более того, если бы такие преобразования были разрешены, то /[^\W]/i совпадали бы с любым символом из a, b, …, h, но не с i или s.

15.10.2.9 AtomEscape #

Для вычисления AtomEscape :: DecimalEscape выполняются следующие шаги:

  1. Вычислить DecimalEscape для получения EscapeValue E.

  2. Если E – символ, то

    1. Пусть ch будет символом для E.

    2. Пусть A будет одноэлементным CharSet, содержащим символ ch.

    3. Вызвать CharacterSetMatcher(A, false) и вернуть результат Matcher.

  3. E должно быть целым числом. Пусть n будет этим целым числом.

  4. Если n=0 или n>NCapturingParens, сгенерировать исключение SyntaxError.

  5. Вернуть внутреннее замкнутое выражение Matcher, принимающее два аргумента – State x и Continuation c, и выполнить следующие шаги:

        1. Пусть cap будет внутренним массивом captures для x.

        2. Пусть s будет cap[n].

        3. Если s равно undefined, вызвать c(x) и вернуть результат.

        4. Пусть e будет endIndex для x.

        5. Пусть len будет длиной для s.

        6. Пусть f будет e+len.

        7. Если f>InputLength, вернуть failure.

        8. Если существует такое целое число i между 0 (включительно) и len (не включительно), чтобы Canonicalize(s[i]) не являлось таким же символом, что и Canonicalize(Input [e+i]), то вернуть failure.

        9. Пусть y будет State (f, cap).

        10. Вызвать c(y) и вернуть результат.

Для вычисления AtomEscape :: CharacterEscape выполняются следующие шаги:

  1. Вычислить CharacterEscape, чтобы получить символ ch.

  2. Пусть A будет одноэлементным CharSet, содержащим символ ch.

  3. Вызвать CharacterSetMatcher(A, false) и вернуть результат Matcher.

Для вычисления AtomEscape :: CharacterClassEscape выполняются следующие шаги:

  1. Вычислить CharacterClassEscape, чтобы получить CharSet A.

  2. Вызвать CharacterSetMatcher(A, false) и вернуть результат Matcher.

ПРИМЕЧАНИЕ Управляющая последовательность, представляющая собой \ с последующим ненулевым десятичным числом n, соответствует результату n-ного набора захватывающих скобок (см. 15.10.2.11). Если регулярное выражение имеет меньше захватывающих скобок, чем n, это является ошибкой. Если регулярное выражение имеет n или более захватывающих скобок, но значение n-ной захватывающей скобки является undefined, поскольку она ничего не захватила, то обратная ссылка всегда считается успешной.

15.10.2.10 CharacterEscape #

Для вычисления CharacterEscape :: ControlEscape возвращается символ в соответствии с Таблицей 23

Таблица 23. Значения символов ControlEscape

ControlEscape

Кодовая единица

Наименование

Символ

t

\u0009

горизонтальная табуляция

<HT>

n

\u000A

перевод строки (новая строка)

<LF>

v

\u000B

вертикальная табуляция

<VT>

f

\u000C

перевод страницы

<FF>

r

\u000D

возврат каретки

<CR>

Для вычисления CharacterEscape :: c ControlLetter выполняются следующие шаги:

  1. Пусть ch будет символом, представленным посредством ControlLetter.

  2. Пусть i будет значением кодовой единицы ch.

  3. Пусть j будет остатком от деления i на 32.

  4. Вернуть кодовую единицу под номером j.

Для вычисления CharacterEscape :: HexEscapeSequence вычислить CV для HexEscapeSequence (см. 7.8.4) и вернуть реузльтат его символа.

Для вычисления CharacterEscape :: UnicodeEscapeSequence вычислить CV для UnicodeEscapeSequence (см. 7.8.4) и вернуть реузльтат его символа.

Для вычисления CharacterEscape :: IdentityEscape вернуть символ, представленный посредством IdentityEscape.

15.10.2.11 DecimalEscape #

Для вычисления DecimalEscape :: DecimalIntegerLiteral [lookahead DecimalDigit] выполняются следующие шаги:

  1. Пусть i будет MV для DecimalIntegerLiteral.

  2. Если i равно нулю, вернуть EscapeValue, состоящее из символа <NUL> (значение Юникода 0000).

  3. Вернуть EscapeValue, состоящее из целого числа i.

Определение MV для DecimalIntegerLiteral” приведено в 7.8.3.

ПРИМЕЧАНИЕ Если после символа \ следует десятичное число n, первая цифра которого не равна 0, то управляющая последовательность считается обратной ссылкой. Если n больше, чем общее количество открывающих захватывающих скобок во всём регулярном выражении, это является ошибкой. Псоледовательность \0 представляет символ <NUL>; после него не может следовать десятичная цифра.

15.10.2.12 CharacterClassEscape #

Для вычисления CharacterClassEscape :: d возвращается набор символов из десяти элементов, содержащий символы от 0 до 9 включительно.

Для вычисления CharacterClassEscape :: D возвращается набор всех символов, не входящих в набор, возвращаемый посредством :: d.

Для вычисления CharacterClassEscape :: s возвращаются набор символов, содержащий символы, расположенные с правой стороны от правил WhiteSpace (7.2) или LineTerminator (7.3).

Для вычисления CharacterClassEscape :: S возвращается набор всех символов, не входящих в набор, возвращаемый посредством :: s.

Для вычисления CharacterClassEscape :: w возвращается набор символов, содержащий шестьдесят три символа:

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

_

Для вычисления CharacterClassEscape :: W возвращается набор всех символов, не входящих в набор, возвращаемый посредством :: w.

15.10.2.13 CharacterClass #

Для вычисления CharacterClass :: [ [lookahead {^}] ClassRanges] вычисляется ClassRanges, чтобы получить CharSet и вернуть этот CharSet и булево false.

Для вычисления CharacterClass :: [ ^ ClassRanges] вычисляется ClassRanges, чтобы получить CharSet и вернуть этот CharSet и булево true.

15.10.2.14 ClassRanges #

Для вычисления ClassRanges:: [empty] возвращается пустой CharSet.

Для вычисления ClassRanges:: NonemptyClassRanges вычисляется NonemptyClassRanges, чтобы получить CharSet и вернуть этот CharSet.

15.10.2.15 NonemptyClassRanges #

Для вычисления NonemptyClassRanges :: ClassAtom вычисляется ClassAtom, чтобы получить CharSet и вернуть этот CharSet.

Для вычисления NonemptyClassRanges :: ClassAtom NonemptyClassRangesNoDash выполняются следующие шаги:

  1. Вычислить ClassAtom, чтобы получить CharSet A.

  2. Вычислить NonemptyClassRangesNoDash, чтобы получить CharSet B.

  3. Вернуть объединение CharSet A и CharSet B.

Для вычисления NonemptyClassRanges :: ClassAtom- ClassAtom ClassRanges выполняются следующие шаги:

  1. Вычислить первый ClassAtom, чтобы получить CharSet A.

  2. Вычислить второй ClassAtom, чтобы получить CharSet B.

  3. Вычислить ClassRanges, чтобы получить CharSet C.

  4. Вызвать CharacterRange(A, B) и пусть D будет полученным CharSet.

  5. Вернуть объединение CharSet D и CharSet C.

Абстрактная операция CharacterRange принимает два параметра CharSet A и B и выполняет следующие действия:

  1. Если A не содержит ровно один символ, или B не содержит ровно один символ, сгенерировать исключение SyntaxError.

  2. Пусть a будет этим единственным символом в CharSet A.

  3. Пусть b будет этим единственным символом CharSet B.

  4. Пусть i будет значением кодовой единицы символа a.

  5. Пусть j будет значением кодовой единицы символа b.

  6. Если i > j, то сгенерировать исключение SyntaxError.

  7. Вернуть набор, содержащий все символы с номерами от i до j включительно.

15.10.2.16 NonemptyClassRangesNoDash #

Для вычисления NonemptyClassRangesNoDash :: ClassAtom вычисляется ClassAtom, чтобы получить CharSet и вернуть этот CharSet.

Для вычисления NonemptyClassRangesNoDash :: ClassAtomNoDash NonemptyClassRangesNoDash выполняются следующие шаги:

  1. Вычислить ClassAtomNoDash, чтобы получить CharSet A.

  2. Вычислить NonemptyClassRangesNoDash, чтобы получить CharSet B.

  3. Вернуть объединение CharSetA и CharSet B.

Для вычисления NonemptyClassRangesNoDash :: ClassAtomNoDash- ClassAtom ClassRanges выполняются следующие шаги:

  1. Вычислить ClassAtomNoDash, чтобы получить CharSet A.

  2. Вычислить ClassAtom, чтобы получить CharSet B.

  3. Вычислить ClassRanges, чтобы получить CharSet C.

  4. Вызвать CharacterRange(A, B) и пусть D будет полученным CharSet.

  5. Вернуть объединение CharSet D и CharSet C.

ПРИМЕЧАНИЕ 1 ClassRanges может быть разложен на одиночные ClassAtoms и/или диапазоны из двух ClassAtoms, разделённых тире. В последнем случае ClassRanges включают все символы между первым ClassAtom и вторым ClassAtom, включительно. Если ClassAtom не является одиночным символом (например, если он представляет собой \w), или если кодовое значение первого ClassAtom больше, чем кодовое значение второго ClassAtom, это является ошибкой.

ПРИМЕЧАНИЕ 2 Даже если шаблон не чувствителен к регистру, важен регистр двух концов диапазона, чтобы определить, какие символы входят в этот диапазон. Например, шаблон /[E-F]/i совпадает только с буквами E, F, e и f. А вот шаблон /[E-f]/i совпадает со всеми буквами стандарта ASCII в верхнем и в нижнем регистре, а также с символами [, \, ], ^, _ и `.

ПРИМЕЧАНИЕ 3 Символ - может интерпретироваться буквально, либо же он может означать диапазон. Он интерпретируется буквально, если он является первым или последним символом ClassRanges, начальным или конечным ограничителем диапазона, или следует сразу же описанием диапазона.

15.10.2.17 ClassAtom #

Для вычисления ClassAtom :: - возвращается CharSet, содержащий один символ -.

Для вычисления ClassAtom :: ClassAtomNoDash вычисляется ClassAtomNoDash, чтобы получить CharSet и вернуть этот CharSet.

15.10.2.18 ClassAtomNoDash #

Для вычисления ClassAtomNoDash :: SourceCharacter но не один из \ или ] или - возвращается одноэлементный CharSet, содержащий символ, представленный посредством SourceCharacter.

Для вычисления ClassAtomNoDash :: \ ClassEscape вычисляется ClassEscape, чтобы получить CharSet и вернуть этот CharSet.

15.10.2.19 ClassEscape #

Для вычисления ClassEscape :: DecimalEscape выполняются следующие шаги:

  1. Вычислить DecimalEscape для получения EscapeValue E.

  2. Если E не является символом, сгенерировать исключение SyntaxError.

  3. Пусть ch будет символом для E.

  4. Вернуть одноэлементный CharSet, содержащий символ ch.

Для вычисления ClassEscape :: b возвращается CharSet, содержащий один символ <BS> (значение Юникода 0008).

Для вычисления ClassEscape :: CharacterEscape вычислить CharacterEscape, чтобы получить символ и вернуть одноэлементный CharSet, содержащий этот символ.

Для вычисления ClassEscape :: CharacterClassEscape вычисляется CharacterClassEscape, чтобы получить CharSet и вернуть этот CharSet.

ПРИМЕЧАНИЕ ClassAtom может использовать любую управляющую последовательность, разрешённую в оставшейся части регулярного выражения, кроме \b, \B и обратных ссылок. Внутри CharacterClass \b означает символ возврата на одну позицию, а \B и обратные ссылки генерируют ошибки. Использование обратной ссылки внутри ClassAtom генерирует ошибку.

15.10.3 Вызов конструктора RegExp как функции #

15.10.3.1 RegExp(pattern, flags) #

Если pattern представляет собой объект R, у которого внутреннее свойство [[Class]] равно "RegExp", а flags равно undefined, вернуть R без изменений. В противном случае вызвать стандартный встроенный конструктор RegExp (15.10.4.1), как если бы он был создан выражением new RegExp( pattern, flags) и вернуть объект, созданный этим конструктором.

15.10.4 Конструктор RegExp #

Если RegExp вызывается как часть выражения new, он является конструктором, так как он инициализирует созданный объект.

15.10.4.1 new RegExp(pattern, flags) #

Если pattern представляет собой объект R, у которого внутреннее свойства [[Class]] равно "RegExp", а flags равно undefined, пусть P будет pattern, используемым для создания R, и пусть F будет flags, используемым для создания R. Если pattern представляет собой объект R, у которого внутреннее свойство [[Class]] равно "RegExp", а flags не равно undefined, сгенерировать исключение TypeError. Иначе, пусть P будет пустой строкой, если pattern равно undefined, а в противном случае будет равно ToString(pattern), и пусть F будет пустой строкой, если flags равно undefined, а в противном случае будет равно ToString(flags).

Если символы из P не имеют синтаксической формы Pattern, сгенерировать исключение SyntaxError. В противном случае, пусть у создаваемого объекта будет внутреннее свойство [[Match]], полученное в результате вычисления ("компилирования") символов для P в качестве Pattern, как описано в пункте 15.10.2.

Если F содержит символ, отличный от символов "g", "i" или "m", или если он содержит один и тот же символ более одного раза, сгенерировать исключение SyntaxError.

Если исключение SyntaxError не сгенерировано, то:

Пусть S будет строкой в формате Pattern, эквивалентом P, в котором определённые символы отключаются, как описано далее. S может быть идентичным P или pattern, или нет; однако, внутренняя процедура, полученная в результате вычисления S в качестве Pattern, должна вести себя так же, как и внутренняя процедура, предоставленная внутренним свойством [[Match]] создаваемого объекта.

Символы / или обратная косая черта \, встречающиеся в шаблоне, в строке S должны отключаться, если это необходимо для того, чтобы строковое значение, полученное в результате конкатенации строк "/", S, "/" и F, могли быть подвергнуты синтаксическому разбору (в соответствующем лексическом контексте) как RegularExpressionLiteral, который ведёт себя аналогично создаваемому регулярному выражению. Например, если P равно "/", то S, среди прочих возможных вариантов, могло бы быть "\/" или "\u002F", но не "/", потому что в результате синтаксического разбора /// с последующим F передавалось бы как SingleLineComment, а не как RegularExpressionLiteral. Если P – пустая строка, то этой спецификации можно соответствовать, если S будет "(?:)".

Следующие свойства создаваемого объекта являются свойствами данных с атрибутами, указанными в пункте 15.10.7. [[Value]] каждого свойства задаётся следующим образом:

Свойству source создаваемого объекта присваивается значение S.

Свойству global создаваемого объекта присваивается булево значение, равное true, если F содержит символ "g", а в противном случае – равное false.

Свойству ignoreCase создаваемого объекта присваивается булево значение, равное true, если F содержит символ "g", а в противном случае – равное false.

Свойству multiline создаваемого объекта присваивается булево значение, равное true, если F содержит символ "g", а в противном случае – равное false.

Свойству multiline создаваемого объекта присваивается значение 0.

Внутреннее свойство [[Prototype]] создаваемого объекта устанавливается равным стандартному встроенному объекту-прототипу RegExp, как указано в пункте 15.10.6.

Внутреннее свойство [[Class]] создаваемого объекта устанавливается равным "RegExp".

ПРИМЕЧАНИЕ Если строка представляет собой StringLiteral, то прежде чем производить обработку строки регулярным выражением, производятся обычные замены управляющей последовательности. Если шаблон содержит управляющую последовательно, распознаваемую регулярным выражением, то символы обратной косой черты \ внутри StringLiteral должны отключаться, чтобы они не удалялись при формировании содержимого StringLiteral.

15.10.5 Свойства конструктора RegExp #

Значением внутреннего свойства [[Prototype]] конструктора RegExp является стандартный встроенный объект-прототип Function (15.3.4).

Кроме внутренних свойств и свойства length со значением 2, конструктор RegExp имеет следующие свойства:

15.10.5.1 RegExp.prototype #

Начальным значением RegExp.prototype является объект-прототип RegExp (15.10.6).

Это свойство имеет атрибуты { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

15.10.6 Свойства объекта-прототипа RegExp #

Значением внутреннего свойства [[Prototype]] объекта-прототипа RegExp является стандартный встроенный объект-прототип Object (15.2.4). Объект-прототип RegExp сам по себе является объектом регулярного выражения. Его [[Class]] равен "RegExp". Начальные значения свойств данных объекта-прототипа RegExp (15.10.7) устанавливаются такими, как если бы этот объект был создан выражением new RegExp(), где RegExp является этим стандартным встроенным конструктором с этим именем.

Объект-прототип RegExp не имеет собственного свойства valueOf, но он наследует свойство valueOf от объекта-прототипа Object.

В приведённых ниже описаниях функций, которые являются свойствами объекта-прототипа RegExp, фраза "объект this типа RegExp" означает объект, который представляет собой значение this, переданное при вызове функции. Если значение this не является объектом, или является объектом, для которого значение внутреннего свойства [[Class]] не равно "RegExp", генерируется исключение TypeError.

15.10.6.1 RegExp.prototype.constructor #

Начальным значением RegExp.prototype.constructor является стандартный встроенный конструктор RegExp.

15.10.6.2 RegExp.prototype.exec(string) #

Производит поиск соответствия регулярному выражению в строке string и возвращает объект Array, содержащий результаты соответствия, или null, если соответствие не найдено.

Поиск по строке ToString(string) экземпляров шаблона регулярного выражения производится следующим образом:

  1. Пусть R будет объектом this типа RegExp.

  2. Пусть S будет значением ToString(string).

  3. Пусть length будет длиной для S.

  4. Пусть lastIndex будет результатом вызова внутреннего метода [[Get]] для R с аргументом "lastIndex".

  5. Пусть i будет значением ToInteger(lastIndex).

  6. Пусть global будет результатом вызова внутреннего метода [[Get]] для R с аргументом "global".

  7. Если global равно false, пусть i = 0.

  8. Пусть matchSucceeded будет false.

  9. Повторять, пока matchSucceeded равно false.

    1. Если i < 0 или i > length, то

      1. Вызвать внутренний метод [[Put]] для R с аргументами "lastIndex", 0 и true.

      2. Вернуть null.

    2. Вызвать внутренний метод [[Match]] для R с аргументами S и i.

    3. Если [[Match]] вернол failure, то

      1. Пусть i = i+1.

    4. else

      1. Пусть r будет результатом State для вызова [[Match]].

      2. Присвоить matchSucceeded значение true.

  10. Пусть e будет значением endIndex для r.

  11. Если global равно true,

    1. Вызвать внутренний метод [[Put]] для R с аргументами "lastIndex", e, и true.

  12. Пусть n будет длиной массива captures для r. (Это точно такое же значение, что и значение NCapturingParens из пункта 15.10.2.1).

  13. Пусть A будет новым массивом, как если бы он был создан выражением new Array(), где Array является стандартным встроенным конструктором с этим именем.

  14. Пусть matchIndex будет позицией совпавшей подстроки в целой строке S.

  15. Вызвать внутренний метод [[DefineOwnProperty]] для A с аргументами "index", Property Descriptor {[[Value]]: matchIndex, [[Writable]: true, [[Enumerable]]: true, [[Configurable]]: true} и true.

  16. Вызвать внутренний метод [[DefineOwnProperty]] для A с аргументами "input", Property Descriptor {[[Value]]: S, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true} и true.

  17. Вызвать внутренний метод [[DefineOwnProperty]] для A с аргументами "length", Property Descriptor {[[Value]]: n + 1} и true.

  18. Пусть matchedSubstr будет совпавшей подстрокой (то есть, частью строки S между смещением i включительтно и смещением e не включительно).

  19. Вызвать внутренний метод [[DefineOwnProperty]] для A с аргументами "0", Property Descriptor {[[Value]]: matchedSubstr, [[Writable]: true, [[Enumerable]]: true, [[Configurable]]: true} и true.

  20. Для каждого такого целого числа i , чтобы I > 0 и I n

    1. Пусть captureI будет элементом № i массива captures для r.

    2. Вызвать внутренний метод [[DefineOwnProperty]] для A с аргументами ToString(i), Property Descriptor {[[Value]]: captureI, [[Writable]: true, [[Enumerable]]: true, [[Configurable]]: true} и true.

  21. Вернуть А.

15.10.6.3 RegExp.prototype.test(string) #

Выполняются следующие шаги:

  1. Пусть match будет результатом вычисления алгоритма RegExp.prototype.exec (15.10.6.2) над объектом this типа RegExp, с использованием string в качестве аргумента.

  2. Если match не равно null, вернуть true; иначе вернуть false.

15.10.6.4 RegExp.prototype.toString() #

Возвращает строковое значение, полученное в результате конкатенации строк "/", строкового значения свойства source объекта this типа RegExp, и "/"; а также "g", если свойство global равно true, "i", если свойства ignoreCase равно true, и "m", если свойство multiline равно true.

ПРИМЕЧАНИЕ Возвращаемая строка имеет формат RegularExpressionLiteral, который преобразуется в другой объект типа RegExp с таким же поведением, что и объект this.

15.10.7 Свойства экземпляров RegExp #

Экземпляры RegExp наследуют свойства объекта-прототипа RegExp. Значение их внутреннего свойства [[Class]] равно "RegExp". Экземпляры RegExp также имеют внутреннее свойство [[Match]] и свойство length.

Значение внутреннего свойства [[Match]] представляет собой зависящее от реализации представление шаблона Pattern объекта типа RegExp.

Кроме того, экземпляры RegExp обладают следующими свойствами:

15.10.7.1 source #

Значение свойства source представляет собой строку в формате Pattern, представляющую текущее регулярное выражение. Это свойство имеет атрибуты { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

15.10.7.2 global #

Значение свойства global представляет собой булево значение, указывающее, содержат ли флаги символ “g”. Это свойство имеет атрибуты { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

15.10.7.3 ignoreCase #

Значение свойства ignoreCase представляет собой булево значение, указывающее, содержат ли флаги символ “i”. Это свойство имеет атрибуты { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

15.10.7.4 multiline #

Значение свойства multiline представляет собой булево значение, указывающее, содержат ли флаги символ “m”. Это свойство имеет атрибуты { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

15.10.7.5 lastIndex #

Значение свойства lastIndex указывает на позицию в строке, с которой начинается следующий поиск совпадения. При использовании оно приводится к целому числу (см. 15.10.6.2). Это свойство имеет атрибуты { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

ПРИМЕЧАНИЕ В отличие от других стандартных встроенных свойства экземпляров RegExp, lastIndex является перезаписываемым свойством.