Регулярные выражения с обратными ссылками — различия между версиями
Daviondk (обсуждение | вклад) (Правки) |
Daviondk (обсуждение | вклад) |
||
Строка 7: | Строка 7: | ||
Каждой группе соответствует порядковый номер. Нумерация идёт слева направо: номеру группы соответствует порядковый номер открывающей круглой скобки этой группы в тексте регулярного выражения. | Каждой группе соответствует порядковый номер. Нумерация идёт слева направо: номеру группы соответствует порядковый номер открывающей круглой скобки этой группы в тексте регулярного выражения. | ||
− | Пример: <tex>(ab(cd))(ef).</tex> Группа №1 {{---}} <tex>(ab(cd)),\,</tex> группа №2 {{---}} <tex>(cd),\,</tex> группа №3 {{---}} <tex>(ef)</tex> | + | Пример: <tex>(ab(cd))(ef).</tex> Группа <tex>№1</tex> {{---}} <tex>(ab(cd)),\,</tex> группа <tex>№2</tex> {{---}} <tex>(cd),\,</tex> группа <tex>№3</tex> {{---}} <tex>(ef)</tex> |
{{Определение | {{Определение | ||
Строка 32: | Строка 32: | ||
# Регулярное выражение <tex>(aba?)c(?1)\,</tex> породит язык <tex>L=\{abcab,abacab,abcaba,abacaba\}.</tex> | # Регулярное выражение <tex>(aba?)c(?1)\,</tex> породит язык <tex>L=\{abcab,abacab,abcaba,abacaba\}.</tex> | ||
# Выразим язык тандемных повторов над алфавитом <tex>\Sigma=\{0,1\},</tex> используя механизм обратных ссылок: | # Выразим язык тандемных повторов над алфавитом <tex>\Sigma=\{0,1\},</tex> используя механизм обратных ссылок: | ||
− | #: <tex>L=((0|1)^∗)\backslash 1.</tex> | + | #: <tex>L=((0\,|\,1)^∗)\backslash 1.</tex> |
#: Данный язык не является [[Регулярные языки: два определения и их эквивалентность|регулярным]], однако его можно представить с помощью регулярных выражений с использованием обратных ссылок. | #: Данный язык не является [[Регулярные языки: два определения и их эквивалентность|регулярным]], однако его можно представить с помощью регулярных выражений с использованием обратных ссылок. | ||
# Выведем регулярное выражение для языка, состоящего из палиндромов фиксированной длины <tex>n=2\cdot m\,</tex> или <tex>\,n=2\cdot m+1</tex>: | # Выведем регулярное выражение для языка, состоящего из палиндромов фиксированной длины <tex>n=2\cdot m\,</tex> или <tex>\,n=2\cdot m+1</tex>: | ||
Строка 68: | Строка 68: | ||
<tex>A\rightarrow a\leftrightarrow A=a;\\S\rightarrow\varepsilon\leftrightarrow S=\varepsilon.</tex> | <tex>A\rightarrow a\leftrightarrow A=a;\\S\rightarrow\varepsilon\leftrightarrow S=\varepsilon.</tex> | ||
− | Если какому-то нетерминалу <tex>A</tex> соответствуют несколько регулярных выражений <tex>r_1, r_2, \dotsc, r_n</tex>, заменить их на одно: <tex>A=((r_1)|(r_2)|\dotsc|(r_n))\,</tex> (очевидно, что оно также будет соответствовать этому нетерминалу). | + | Если какому-то нетерминалу <tex>A</tex> соответствуют несколько регулярных выражений <tex>r_1, r_2, \dotsc, r_n</tex>, заменить их на одно: <tex>A=((r_1)\,|\,(r_2)\,|\,\dotsc\,|\,(r_n))\,</tex> (очевидно, что оно также будет соответствовать этому нетерминалу). |
Регулярное выражение для <tex>S</tex> будет искомым. | Регулярное выражение для <tex>S</tex> будет искомым. | ||
Строка 81: | Строка 81: | ||
Эквивалентным будет выражение <tex>(((b\,|\,c)\,(?1)?)?).</tex> | Эквивалентным будет выражение <tex>(((b\,|\,c)\,(?1)?)?).</tex> | ||
+ | |||
Другой пример: | Другой пример: | ||
Строка 86: | Строка 87: | ||
<tex>S\rightarrow AB\\S\rightarrow\varepsilon\\A\rightarrow SS\\B\rightarrow CD\\C\rightarrow c\\D\rightarrow d</tex> | <tex>S\rightarrow AB\\S\rightarrow\varepsilon\\A\rightarrow SS\\B\rightarrow CD\\C\rightarrow c\\D\rightarrow d</tex> | ||
− | + | Допустим, группа <tex>№1</tex> соответствует нетерминалу <tex>S,\,</tex> группы <tex>№2-№5</tex> {{---}} нетерминалам <tex>A-D</tex> соответственно. | |
+ | # Для каждого нетерминала составим регулярное выражение: | ||
+ | #: <tex>S\leftrightarrow ((?2)(?3))\\S\leftrightarrow\varepsilon\\A\leftrightarrow ((?1)(?1))\\B\leftrightarrow ((?4)(?5))\\C\leftrightarrow c\\D\leftrightarrow d</tex> | ||
+ | # Объединим регулярные выражения, соответствующие одинаковым нетерминалам: | ||
+ | #: <tex>S\leftrightarrow (((?2)(?3))\,|\,\varepsilon)\\A\leftrightarrow ((?1)(?1))\\B\leftrightarrow ((?4)(?5))\\C\leftrightarrow c\\D\leftrightarrow d</tex> | ||
+ | # Искомое регулярное выражение соответствует нетерминалу <tex>S,\,</tex> однако оно ссылается на группы, отличные от <tex>S.</tex> Будем рекурсивно заменять такие ссылки на сами регулярные выражения до тех пор, пока в исходном регулярном выражении не останутся только терминалы и ссылки на стартовый нетерминал <tex>S</tex>: | ||
+ | #: <tex>(((?2)(?3))\,|\,\varepsilon)\rightarrow(((?1)(?1)(?3))\,|\,\varepsilon)\rightarrow(((?1)(?1)(?4)(?5))\,|\,\varepsilon)\rightarrow(((?1)(?1)c(?5))\,|\,\varepsilon)\rightarrow(((?1)(?1)cd)\,|\,\varepsilon).</tex> | ||
+ | |||
+ | Таким образом, регулярное выражение для этой грамматики будет выглядеть так: <tex>(((?1)(?1)cd)\,|\,\varepsilon).</tex> | ||
==Применение== | ==Применение== | ||
С помощью обратных ссылок можно составить регулярные выражения для языка тандемных повторов и других языков, где требуется «запоминать» части входящих в язык слов. | С помощью обратных ссылок можно составить регулярные выражения для языка тандемных повторов и других языков, где требуется «запоминать» части входящих в язык слов. |
Версия 20:18, 29 мая 2018
Содержание
Базовые определения
Определение: |
Группа (англ. capture group) — часть регулярного выражения. Группа заключается в круглые скобки. |
Каждой группе соответствует порядковый номер. Нумерация идёт слева направо: номеру группы соответствует порядковый номер открывающей круглой скобки этой группы в тексте регулярного выражения.
Пример:
Группа — группа — группа —
Определение: |
Обратная ссылка (англ. backreference) — механизм повторного использования групп или слов группы. |
Для повторного использования слова группы используется обозначение где — номер группы.
Пример использования:
Данное регулярное выражение будет допускать только слова, в которых количество букв чётно.Для повторного использования регулярного выражения группы используется обозначение
где — номер группы. Использование круглых скобок обусловленно тем, что как управляющий символ уже используется.
Обратите внимание, что символы круглых скобок и обратной косой являются управляющими. Чтобы использовать их непосредственно как часть слова, их нужно экранировать.
Пример экранирования (в данном случае в качестве символа экранирования используется символ обратной косой черты):
— обратная ссылка на первую группу, — слово, состоящее из символа обратной косой черты и единицы.
Определение: |
Регулярные выражения с обратными ссылками (англ. regex with backreferences) — регулярные выражения, использующие механизм обратных ссылок. |
Примеры
- Регулярное выражение породит язык
- Выразим язык тандемных повторов над алфавитом
- Данный язык не является регулярным, однако его можно представить с помощью регулярных выражений с использованием обратных ссылок.
используя механизм обратных ссылок:
- Выведем регулярное выражение для языка, состоящего из палиндромов фиксированной длины
- для чётного :
- для нечётного :
- где – любой одиночный символ.
или :
- Запишем выражение для языка лемме о разрастании), то есть является контекстно-зависимым, но также легко представим с помощью обратных ссылок:
- .
Данный язык не является ни регулярным, ни контекстно-свободным (по - Язык
- Следущий за ссылкой знак вопроса обозначает использование группы или раз, то есть осуществление рекурсивного вызова или его окончание.
-
- Очевидно, что все слова из языка удовлетворяют данному регулярному выражению.
можно представить при помощи обратных ссылок:
Теорема о КС-языках
Теорема: |
С помощью механизма обратных ссылок можно представить любой контекстно-свободный язык. |
Доказательство: |
Любую контекстно-свободную грамматику можно привести к нормальной форме Хомского, следовательно, достаточно доказать, что грамматику, заданную в такой форме, можно преобразовать в регулярное выражение с обратными ссылками. Рассмотрим правила, которые могут содержаться в такой грамматике:
Представим каждое из них в виде регулярного выражения с обратными ссылками. Используя ссылки на регулярные выражения, соответствующие нетерминалам и , можно представить первое правило:где и соответствуют нетерминалам и ; Второе и третье правила не требуют использования обратных ссылок:
Если какому-то нетерминалу Регулярное выражение для соответствуют несколько регулярных выражений , заменить их на одно: (очевидно, что оно также будет соответствовать этому нетерминалу). будет искомым. |
Регулярные выражения с обратными ссылками имеют бо́льшую мощность по сравнению с обычными. С их помощью реализуются как регулярные языки, так и контекстно-свободные грамматики, а также некоторые контекстно-зависимые (см. пример 4).
Примеры преобразования
Рассмотрим следующую КС-грамматику:
Эквивалентным будет выражение
Другой пример:
Допустим, группа
соответствует нетерминалу группы — нетерминалам соответственно.- Для каждого нетерминала составим регулярное выражение:
- Объединим регулярные выражения, соответствующие одинаковым нетерминалам:
- Искомое регулярное выражение соответствует нетерминалу
Таким образом, регулярное выражение для этой грамматики будет выглядеть так:
Применение
С помощью обратных ссылок можно составить регулярные выражения для языка тандемных повторов и других языков, где требуется «запоминать» части входящих в язык слов.
Регулярные выражения в языках программирования зачастую поддерживают обратные ссылки. На практике их можно использовать, например, для парсинга
-выражений (поиск подстрок, содержащихся в определённых тегах).См. также
- Регулярные языки: два определения и их эквивалентность
- Контекстно-свободные грамматики, вывод, лево- и правосторонний вывод, дерево разбора
- Нормальная форма Хомского
- Иерархия Хомского формальных грамматик