|
|
Строка 1: |
Строка 1: |
− | {| class="wikitable" align="center" style="color: red; background-color: black; font-size: 56px; width: 800px;"
| |
− | |+
| |
− | |-align="center"
| |
− | |'''НЕТ ВОЙНЕ'''
| |
− | |-style="font-size: 16px;"
| |
− | |
| |
− | 24 февраля 2022 года российское руководство во главе с Владимиром Путиным развязало агрессивную войну против Украины. В глазах всего мира это военное преступление совершено от лица всей страны, всех россиян.
| |
− |
| |
− | Будучи гражданами Российской Федерации, мы против своей воли оказались ответственными за нарушение международного права, военное вторжение и массовую гибель людей. Чудовищность совершенного преступления не оставляет возможности промолчать или ограничиться пассивным несогласием.
| |
− |
| |
− | Мы убеждены в абсолютной ценности человеческой жизни, в незыблемости прав и свобод личности. Режим Путина — угроза этим ценностям. Наша задача — обьединить все силы для сопротивления ей.
| |
− |
| |
− | Эту войну начали не россияне, а обезумевший диктатор. И наш гражданский долг — сделать всё, чтобы её остановить.
| |
− |
| |
− | ''Антивоенный комитет России''
| |
− | |-style="font-size: 16px;"
| |
− | |Распространяйте правду о текущих событиях, оберегайте от пропаганды своих друзей и близких. Изменение общественного восприятия войны - ключ к её завершению.
| |
− | |-style="font-size: 16px;"
| |
− | |[https://meduza.io/ meduza.io], [https://www.youtube.com/c/popularpolitics/videos Популярная политика], [https://novayagazeta.ru/ Новая газета], [https://zona.media/ zona.media], [https://www.youtube.com/c/MackNack/videos Майкл Наки].
| |
− | |}
| |
− |
| |
| ==Базовые определения== | | ==Базовые определения== |
| {{Определение | | {{Определение |
Базовые определения
Определение: |
Группа (англ. capture group) — часть регулярного выражения. Общепринятое условное обозначение группы — круглые скобки. |
Пример: [math]aba(ca)ba.\,[/math] В данном регулярном выражении представлена одна группа — [math](ca).[/math]
Каждой группе соответствует порядковый номер. Нумерация идёт слева направо: номеру группы соответствует порядковый номер открывающей круглой скобки этой группы в тексте регулярного выражения (исключая случаи, когда скобки являются частью синтаксической конструкции).
Пример: [math](ab(cd))(ef).[/math] Группа [math]№1[/math] — [math](ab(cd)),\,[/math] группа [math]№2[/math] — [math](cd),\,[/math] группа [math]№3[/math] — [math](ef)[/math]
Определение: |
Обратная ссылка (англ. backreference) — механизм повторного использования групп или слов группы. |
Для повторного использования слова группы используется обозначение [math]\backslash n,\,[/math] где [math]n[/math] — номер группы.
Пример использования: [math]((1\,|\,0)^*)\backslash 1.\,[/math] Данное регулярное выражение будет задавать язык тандемных повторов. Несмотря на то, что он не является регулярным, его можно представить с помощью механизма обратных ссылок.
Для повторного использования регулярного выражения группы используется обозначение [math](?n),\,[/math] где [math]n[/math] — номер группы. Использование круглых скобок обусловленно тем, что [math]?,[/math] как управляющий символ, уже используется. В данном случае круглые скобки следует воспринимать как общепринятое условное обозначение обратной ссылки; запись [math](?n)[/math] не задаёт группу. Например, в выражении [math](aba)(?1)(caba)(?2)\;[/math] ссылке [math](?2)[/math] будет соответствовать [math](caba),\,[/math] а не [math](?1).[/math]
Обратите внимание, что символы круглых скобок и обратной косой черты являются управляющими. Чтобы использовать их непосредственно как часть слова, их нужно экранировать.
Пример экранирования (в данном случае в качестве символа экранирования используется символ обратной косой черты): [math]\backslash 1[/math] — обратная ссылка на первую группу, [math]\backslash\backslash 1[/math] — слово, состоящее из символа обратной косой черты и единицы.
Определение: |
Регулярные выражения с обратными ссылками (англ. regex with backreferences) — регулярные выражения, использующие механизм обратных ссылок. |
Примеры
- Регулярное выражение [math](aba?)c(?1)\,[/math] породит язык [math]L=\{abcab,abacab,abcaba,abacaba\}.\;[/math] Для сравнения, запишем эквивалентное регулярное выражение без использования механизма обратных ссылок: [math](aba?)c(aba?).[/math]
- [math](a^*)\backslash 1.\,[/math] Данное регулярное выражение будет допускать только слова, в которых количество букв [math]a[/math] чётно.
- Выведем регулярное выражение для языка, состоящего из палиндромов фиксированной длины [math]n=2\cdot m\,[/math] или [math]\,n=2\cdot m+1[/math] над алфавитом [math]\Sigma=\{0,1\}[/math]:
- для чётного [math]n[/math]: [math]\;\underbrace{(0\,|\,1)(0\,|\,1)(0\,|\,1)\dotsc(0\,|\,1)}_{m}\,\backslash m\dotsc\backslash 3\backslash 2\backslash 1;[/math]
- для нечётного [math]n[/math]: [math]\;\underbrace{(0\,|\,1)(0\,|\,1)(0\,|\,1)\dotsc(0\,|\,1)}_{m}\,(0\,|\,1)\backslash m\dotsc\backslash 3\backslash 2\backslash 1,\;[/math]
- Запишем выражение для языка [math]L=b^kab^kab^ka,\,k\gt 0.\,[/math] Данный язык не является ни регулярным, ни контекстно-свободным (по лемме о разрастании), то есть является контекстно-зависимым, но также легко представим с помощью обратных ссылок:
- [math]L=(bb^*a)\backslash 1\backslash 1[/math].
- Язык [math]L=a^nb^n,\,n\gt 0\,[/math] можно представить при помощи обратных ссылок:
- [math]L=(a(?1)?b).[/math]
- Следущий за ссылкой [math](?1)[/math] знак вопроса обозначает использование группы [math]0[/math] или [math]1[/math] раз, то есть осуществление рекурсивного вызова или его окончание.
- [math](?1)[/math] ссылается на первую группу — [math](a(?1)?b)[/math], что равносильно рекурсивной зависимости:
- [math](a(?1)?b)=[/math]
- [math]=(a(a(?1)?b)?b)=[/math]
- [math]=(a(a(a(?1)?b)?b)?b)=[/math]
- [math]=(a(a(a(a(?1)?b)?b)?b)?b)=\dotsc[/math]
- Очевидно, что все слова из языка [math]L[/math] удовлетворяют данному регулярному выражению.
Теорема о КС-языках
Теорема: |
|
Доказательство: |
[math]\triangleright[/math] |
Любую контекстно-свободную грамматику можно привести к нормальной форме Хомского, следовательно, достаточно доказать, что грамматику, заданную в такой форме, можно преобразовать в регулярное выражение с обратными ссылками. Рассмотрим правила, которые могут содержаться в такой грамматике:
[math]A\rightarrow BC\\A\rightarrow a\\S\rightarrow\varepsilon[/math]
Представим каждое из них в виде регулярного выражения с обратными ссылками.
Используя ссылки на регулярные выражения, соответствующие нетерминалам [math]B[/math] и [math]C[/math], можно представить первое правило:
[math]A\rightarrow BC\leftrightarrow A\rightarrow ((?n_B)\,(?n_C)),\,[/math] где [math](?n_B)[/math] и [math](?n_C)[/math] соответствуют нетерминалам [math]B[/math] и [math]C[/math];
Второе и третье правила не требуют использования обратных ссылок:
[math]A\rightarrow a\leftrightarrow A\rightarrow (a);\\S\rightarrow\varepsilon\leftrightarrow S\rightarrow ().[/math]
Если какому-то нетерминалу [math]A[/math] соответствуют несколько регулярных выражений [math]r_1, r_2, \dotsc, r_n[/math], заменить их на одно: [math]A=(r_1\,|\,r_2\,|\,\dotsc\,|\,r_n)\,[/math] (очевидно, что оно также будет соответствовать этому нетерминалу).
Регулярное выражение для данной КС-грамматики соответствует нетерминалу [math]S,\,[/math] однако в нём могут встречаться ссылки на внешние — отличные от [math]S[/math] — группы. Будем обрабатывать такие ссылки, используя метод левостороннего вывода. При обработке очередной ссылки:
- если эта ссылка встречается впервые, вместо неё подставим соответствующее регулярное выражение и запомним номер его группы в текущем регулярном выражении;
- иначе вместо этой ссылки подставим ссылку на соответствующую группу в текущем регулярном выражении.
После соответствующих замен регулярное выражение для [math]S[/math] будет искомым. |
[math]\triangleleft[/math] |
Пример преобразования
Рассмотрим следующую КС-грамматику:
[math]S\rightarrow cA\\S\rightarrow dA\\S\rightarrow cB\\S\rightarrow eB\\A\rightarrow a\\B\rightarrow b[/math]
- Приведём её к нормальной форме Хомского:
- [math]S\rightarrow CA\\S\rightarrow DA\\S\rightarrow CB\\S\rightarrow EB\\A\rightarrow a\\B\rightarrow b\\C\rightarrow c\\D\rightarrow d\\E\rightarrow e[/math]
- Каждому нетерминалу поставим в соответствие свой номер:
- [math]S\leftrightarrow 1, A\leftrightarrow 2, B\leftrightarrow 3, C\leftrightarrow 4, D\leftrightarrow 5, E\leftrightarrow 6[/math]
- Каждое правило представим в виде регулярного выражения с обратными ссылками:
- [math]S\rightarrow ((?4)(?2))\\S\rightarrow ((?5)(?2))\\S\rightarrow ((?4)(?3))\\S\rightarrow ((?6)(?3))\\A\rightarrow (a)\\B\rightarrow (b)\\C\rightarrow (c)\\D\rightarrow (d)\\E\rightarrow (e)[/math]
- Объединим регулярные выражения, соответствующие одинаковым нетерминалам:
- [math]S\rightarrow (((?4)(?2))\,|\,((?5)(?2))\,|\,((?4)(?3))\,|\,((?6)(?3)))\\A\rightarrow (a)\\B\rightarrow (b)\\C\rightarrow (c)\\D\rightarrow (d)\\E\rightarrow (e)[/math]
- Избавимся от внешних ссылок в регулярном выражении для [math]S[/math]:
Пошаговый вывод
№ |
Текущее регулярное выражение
|
1. |
[math](((\underline{\textbf{?4}})(\underline{?2}))\,|\,((\underline{?5})(\underline{?2}))\,|\,((\underline{?4})(\underline{?3}))\,|\,((\underline{?6})(\underline{?3})))\,[/math]
|
2. |
[math](((c)(\underline{\textbf{?2}}))\,|\,((\underline{?5})(\underline{?2}))\,|\,((\underline{?4})(\underline{?3}))\,|\,((\underline{?6})(\underline{?3})))\,[/math]
|
3. |
[math](((c)(a))\,|\,((\underline{\textbf{?5}})(\underline{?2}))\,|\,((\underline{?4})(\underline{?3}))\,|\,((\underline{?6})(\underline{?3})))\,[/math]
|
4. |
[math](((c)(a))\,|\,((d)(\underline{\textbf{?2}}))\,|\,((\underline{?4})(\underline{?3}))\,|\,((\underline{?6})(\underline{?3})))\,[/math]
|
5. |
[math](((c)(a))\,|\,((d)(?4))\,|\,((\underline{\textbf{?4}})(\underline{?3}))\,|\,((\underline{?6})(\underline{?3})))\,[/math]
|
6. |
[math](((c)(a))\,|\,((d)(?4))\,|\,((?3)(\underline{\textbf{?3}}))\,|\,((\underline{?6})(\underline{?3})))\,[/math]
|
7. |
[math](((c)(a))\,|\,((d)(?4))\,|\,((?3)(b))\,|\,((\underline{\textbf{?6}})(\underline{?3})))\,[/math]
|
8. |
[math](((c)(a))\,|\,((d)(?4))\,|\,((?3)(b))\,|\,((e)(\underline{\textbf{?3}})))\,[/math]
|
9. |
[math](((c)(a))\,|\,((d)(?4))\,|\,((?3)(b))\,|\,((e)(?8)))\,[/math]
|
№ группы в [math]S[/math]
[math]S[/math] |
[math]A[/math] |
[math]B[/math] |
[math]C[/math] |
[math]D[/math] |
[math]E[/math]
|
1 |
|
|
|
|
|
1 |
|
|
3 |
|
|
1 |
4 |
|
3 |
|
|
1 |
4 |
|
3 |
6 |
|
1 |
4 |
|
3 |
6 |
|
1 |
4 |
|
3 |
6 |
|
1 |
4 |
8 |
3 |
6 |
|
1 |
4 |
8 |
3 |
6 |
10
|
1 |
4 |
8 |
3 |
6 |
10
|
Напоминание: круглые скобки в записи обратной ссылки являются синтаксической конструкцией и не задают группу.
Таким образом, регулярное выражение для данной грамматики будет выглядеть так: [math](((c)(a))\,|\,((d)(?4))\,|\,((?3)(b))\,|\,((e)(?8))).[/math]
Рассмотрим другой пример:
[math]S\rightarrow\varepsilon\\S\rightarrow (S)S\\S\rightarrow S(S)[/math]
- Приведём её к нормальной форме Хомского:
- [math]S\rightarrow\varepsilon\\S\rightarrow AS\\S\rightarrow SA\\A\rightarrow OB\\B\rightarrow SC\\O\rightarrow (\\C\rightarrow\; )[/math]
- Каждому нетерминалу поставим в соответствие свой номер:
- [math]S\leftrightarrow 1, A\leftrightarrow 2, B\leftrightarrow 3, O\leftrightarrow 4, C\leftrightarrow 5[/math]
- Каждое правило представим в виде регулярного выражения с обратными ссылками:
- [math]S\rightarrow ()\\S\rightarrow ((?2)(?1))\\S\rightarrow ((?1)(?2))\\A\rightarrow ((?4)(?3))\\B\rightarrow ((?1)(?5))\\O\rightarrow (\backslash (\,)\\C\rightarrow (\backslash )\,)[/math]
- Объединим регулярные выражения, соответствующие одинаковым нетерминалам:
- [math]S\rightarrow (()\,|\,((?2)(?1))\,|\,((?1)(?2)))\\A\rightarrow ((?4)(?3))\\B\rightarrow ((?1)(?5))\\O\rightarrow (\backslash (\,)\\C\rightarrow (\backslash )\,)[/math]
- Избавимся от внешних ссылок в регулярном выражении для [math]S[/math]:
Пошаговый вывод
№ |
Текущее регулярное выражение
|
1. |
[math](()\,|\,((\underline{\textbf{?2}})(?1))\,|\,((?1)(\underline{?2})))[/math]
|
2. |
[math](()\,|\,(((\underline{\textbf{?4}})(\underline{?3}))(?1))\,|\,((?1)(\underline{?2})))[/math]
|
3. |
[math](()\,|\,(((\backslash (\,)(\underline{\textbf{?3}}))(?1))\,|\,((?1)(\underline{?2})))[/math]
|
4. |
[math](()\,|\,(((\backslash (\,)((?1)(\underline{\textbf{?5}})))(?1))\,|\,((?1)(\underline{?2})))[/math]
|
5. |
[math](()\,|\,(((\backslash (\,)((?1)(\backslash )\,)))(?1))\,|\,((?1)(\underline{\textbf{?2}})))[/math]
|
6. |
[math](()\,|\,(((\backslash (\,)((?1)(\backslash )\,)))(?1))\,|\,((?1)(?4)))[/math]
|
№ группы в [math]S[/math]
[math]S[/math] |
[math]A[/math] |
[math]B[/math] |
[math]O[/math] |
[math]C[/math]
|
1 |
|
|
|
|
1 |
4 |
|
|
|
1 |
4 |
|
5 |
|
1 |
4 |
6 |
5 |
|
1 |
4 |
6 |
5 |
7
|
1 |
4 |
6 |
5 |
7
|
Таким образом, регулярное выражение для данной грамматики будет выглядеть так: [math](()\,|\,(((\backslash (\,)((?1)(\backslash )\,)))(?1))\,|\,((?1)(?4))).[/math]
Применение
Регулярные выражения с обратными ссылками имеют бо́льшую мощность по сравнению с обычными. С их помощью реализуются как регулярные языки, так и контекстно-свободные грамматики, а также некоторые контекстно-зависимые (например, язык тандемных повторов).
Регулярные выражения в языках программирования зачастую поддерживают обратные ссылки. На практике их можно использовать, например, для парсинга [math]html[/math]-выражений (поиск подстрок, содержащихся в определённых тегах).
См. также
Источники информации