
Регулярные выражения в основном используются для обработки строк, и их очень удобно использовать для сопоставления, извлечения и замены строк.
Однако изучение регулярных выражений по-прежнему довольно сложно. Такие концепции, как жадное сопоставление, нежадное сопоставление, подгруппы с захватом и подгруппы без захвата, сложны для понимания не только новичкам, но и многим людям, которые работали несколько лет.
Так как же лучше всего изучать регулярные выражения? Как быстро освоить регулярные выражения?
Я рекомендую способ изучения обычных правил, который, на мой взгляд, очень хорош: обучение с помощью AST .
Принцип сопоставления регулярных выражений заключается в анализе строки шаблона в AST, а затем использовании этого AST для сопоставления целевой строки.
Различная информация в строке шаблона будет сохранена в AST после анализа. AST — это абстрактное синтаксическое дерево. Как следует из названия, это дерево, организованное в соответствии с грамматической структурой. Из структуры AST вы можете легко узнать синтаксис, поддерживаемый регулярными выражениями.
Как просмотреть AST регулярного выражения?
Посмотреть визуально можно через сайт asexplorer.net:

Переключив язык синтаксического анализа на RegExp, вы можете визуализировать AST регулярных выражений.
Как упоминалось ранее, AST представляет собой дерево, организованное в соответствии с грамматикой, поэтому из его структуры можно легко выделить различные грамматики.
Затем давайте изучим различные синтаксисы с точки зрения AST:
Начнем с простого /abc/ Такой регулярный текст может соответствовать строке «abc», и его AST выглядит следующим образом:

3 Char, значения a, b, c соответственно, тип простой. Последующее сопоставление заключается в обходе AST и сопоставлении этих трех символов соответственно.
Мы протестировали это с помощью exec API:

0-й элемент — это совпавшая строка, а index — начальный индекс совпавшей строки. input — это входная строка.
Давайте снова попробуем использовать специальные символы:
/ddd/ означает совпадение трех чисел. d — это метасимвол (метасимвол) со специальным значением, поддерживаемый регулярными выражениями.
С помощью AST мы также можем видеть, что хотя они также являются Char, их тип действительно является мета:

Любое число можно сопоставить с помощью метасимвола d:

Какие из них являются метасимволами, а какие простыми символами, можно сразу увидеть с помощью AST.
Regular поддерживает указание набора символов через [], что означает, что он может соответствовать любому из символов.
Мы также можем видеть из AST, что он обернут слоем символов, что означает класс символов, то есть он может соответствовать любому содержащемуся в нем символу.

Это действительно тот случай, который тестируется:

Регулярные выражения поддерживают указание количества повторений определенного символа в форме {from,to},
например, /b{1,3}/ означает, что символ b повторяется от 1 до 3 раз. , /[abc ]{1,3}/ означает, что этот класс символов a/b/c повторяется от 1 до 3 раз.
Как видно из AST, этот синтаксис называется повторением:

У него есть атрибут квантификатора, который представляет квантификатор. Тип здесь — диапазон от 1 до 3.
Регулярные выражения также поддерживают сокращения некоторых квантификаторов, например, +, указывающий от 1 до бесчисленного количества раз, *, обозначающий 0, до бесчисленного количества раз, и ?, обозначающий 0 или 1 раз.
Это разные типы кванторов:

Некоторые студенты могут спросить, что здесь означает атрибут жадности?

Жадный означает жадный. Этот атрибут указывает, является ли это повторение жадным или нежадным совпадением.
Если вы добавите ? после квантификатора, вы обнаружите, что жадное сопоставление становится ложным, что означает переключение на нежадное сопоставление:

Так что же значит жадный и нежадный?
Давайте посмотрим пример.

Сопоставление повторений по умолчанию является жадным и будет продолжаться до тех пор, пока выполняются условия, поэтому здесь можно сопоставить acbac.
Добавление ? после того, как квантификатор переключится на нежадный, и будет сопоставлен только первый:

Это жадное и нежадное сопоставление. С помощью AST мы можем четко знать , что жадное и нежадное сопоставление предназначены для повторения грамматики. Добавьте знак ? после квантификатора, чтобы переключиться на нежадное сопоставление.
Регулярное выражениеподдерживает помещение части совпавшей строки в подгруппу и возврат ее через ().
Посмотрите AST:

Соответствующий AST называется Group.
И вы обнаружите, что у него есть атрибут захвата, который по умолчанию имеет значение true:

Что это значит?
Это синтаксис для захвата подгруппы.
Если вы не хотите захватывать подгруппы, вы можете написать так (?:aaa)

Смотри, захват стал фальшивым.
В чем разница между захватом и не захватом?
Давайте попробуем:

О, оказывается, атрибут захвата группы определяет, следует ли извлекать данные или нет.
Из AST мы видим , что захват предназначен для подгрупп. По умолчанию используется захват, что означает, что содержимое подгруппы извлекается. Вы можете переключиться на отсутствие захвата с помощью ?: и содержимое подгруппы не будет извлечено.
Мы уже знакомы с использованием AST для понимания регулярного синтаксиса, но давайте посмотрим на что-то более сложное:
Регулярные выражения поддерживают выражение упреждающих утверждений через синтаксис (?=xxx), который используется для оценки определенного символа. Предшествует ли строке определенная строка.
Через AST вы можете видеть, что этот синтаксис называется Assertion, а тип — Lookahead, что означает просмотр вперед, соответствующий только предыдущему значению:

Что это значит? Почему ты это пишешь? В чем разница между /bbb(ccc)/ и /bbb(?:ccc)/?
Давайте попробуем:

Это видно из результатов:
/bbb(ccc)/ соответствует подгруппе ccc и извлекает эту подгруппу, поскольку захвачена подгруппа по умолчанию.
/bbb(?:ccc)/ соответствует подгруппе ccc, но не извлекается, поскольку мы установили, что подгруппа не захватывается через ?:.
/bbb(?=ccc)/ Подгруппа, соответствующая ccc, не извлекается, что указывает на то, что она также не фиксируется. Разница между ним и ?: заключается в том, что ccc не отображается в результате сопоставления.
Такова природа утверждения просмотра вперед: утверждение просмотра вперед означает, что определенной строке предшествует определенная строка, соответствующая подгруппа не захватывается, и утвержденная строка не будет отображаться в результате сопоставления.
Если за ней не следует эта строка, она не будет соответствовать:

Измените ?= на ?! Тогда значение изменится.

Хотя утверждение просмотра вперед по-прежнему утверждается первым, существует дополнительный отрицательный атрибут true.
Смысл очевиден. Первоначально это означает, что передняя часть — это определенная строка. После отрицания это означает, что передняя часть не является определенной строкой.
Тогда результат сопоставления будет прямо противоположным:

Теперь он соответствует только в том случае, если перед ним не находится определенная строка. Это утверждение отрицательного просмотра.
Если существует предшествующее утверждение, то, естественно, будет и завершающее утверждение, то есть оно будет соответствовать только в том случае, если за ним следует определенная строка.

Таким же образом можно и отрицать:

Легко придумать AST, соответствующий (?<=aaa), который представляет собой утверждение ретроспективного просмотра:

AST, соответствующий (?<!aaa), предназначен для добавления отрицательного атрибута:

Утверждение просмотра вперед и утверждение просмотра назад — самый сложный для понимания синтаксис регулярных выражений. Гораздо ли проще его понять, если вы изучите его с помощью AST ~
Регулярные выражения — очень удобный инструмент для обработки строк, но это все же несколько сложно. Трудно изучить. Многие люди путаются в синтаксисе, таком как жадное сопоставление, нежадное сопоставление, захватывающие подгруппы, нефиксирующие подгруппы, утверждения просмотра вперед, утверждения просмотра назад и т. д.
Я рекомендую изучать обычные правила с помощью AST. AST — это дерево объектов, организованное в соответствии с грамматической структурой. Различные синтаксисы можно легко разъяснить с помощью имен и атрибутов узлов AST.
Например, мы уточнили с помощью AST:
синтаксис повторения (Повторение) имеет форму символа + квантификатора. По умолчанию используется жадное сопоставление (жадное соответствие истинно), что означает совпадение до тех пор, пока совпадение не будет установлено. -жадное сопоставление, остановка при совпадении одного символа.
Синтаксис подгруппы (Group) используется для извлечения определенной строки. По умолчанию используется захват (захват имеет значение true), что означает, что требуется извлечение. Вы можете переключиться на отсутствие захвата с помощью (?:xxx), который только находит, но не извлекает. .
Синтаксис утверждения (Утверждение) представляет собой определенную строку до или после него. Он разделен на утверждение просмотра вперед и утверждение просмотра назад. Синтаксис: (?=xxx) и (?<=xxx) соответственно. Вы можете передать replace = с помощью ! отрицание (отрицательное истинно), что означает прямо противоположное.
Это глубокое понимание синтаксиса различных документов или глубокое понимание синтаксиса компилятора?
Не надо спрашивать, это должен быть компилятор!
Тогда естественно лучше изучать грамматику через синтаксическое дерево, разобранное по грамматике, чем через документ.
Это справедливо для регулярных выражений, а также для изучения других грамматик. Если вы можете изучить грамматику с помощью AST, вам не нужно читать документацию.