1 <appendix id="regular-expressions">
5 >&Anders.Lund; &Anders.Lund.mail;</author>
6 <othercredit role="translator"
18 >Перевод на русский</contrib
25 >Регулярные выражения</title>
28 >Это приложение содержит краткое, но, надеюсь, достаточно ясное введение в мир <emphasis
29 >регулярных выражений</emphasis
30 >. Здесь описаны регулярные выражения в той форме, в которой они используются в &kate;; к сожалению, они не совместимы с с регулярными выражениями perl и <command
41 >Регулярные выражения</emphasis
42 > - это средство, позволяющее описывать содержание строк в некотором формализованном виде, что даёт возможность приложениям определять принадлежность той или иной строки определённому формату. В дополнение ко всему некоторые приложения могут сохранять части совпавшей строки для их последующего использования.</para>
45 >Приведём небольшой пример. Допустим, вы хотите найти в тексте все абзацы, которые начинаются с фамилий <quote
49 >, за которыми следует любая форма глагола <quote
51 > (для чистоты эксперимента возьмём всего две формы <quote
58 >С помощью обычного поиска вам бы понадобилось сначала найти фамилию <quote
60 >, возможно, дополненную буквами <quote
62 >, что-то вроде этого: <userinput
63 >Петров рассказ</userinput
64 >. При поиске совпадений пришлось бы пропускать все те строки, что стоят не в начале абзаца. После этого последовал бы повторный поиск для второй фамилии...</para>
67 >Регулярные выражения позволяют произвести такую операцию поиска за один раз, причём с гораздо большей точностью.</para>
70 >Регулярные выражения содержат правила, позволяющие точно выразить вид строки для поиска. Наш пример можно выразить словесно: <quote
71 >Строка, начинающаяся со слов <quote
75 >, перед которыми могут стоять до четырёх пробелов или символов табуляции, после фамилии должен стоять пробел, за пробелом - <quote
77 >, после чего может (необязательно!) стоять суффикс <quote
79 >, и, наконец, суффикс <quote
82 >. Посмотрите, как это можно записать в форме регулярного выражения:</para
85 >^[ \t]{0,4}(Петров|Иванов) рассказ(ыв)?ал</userinput
89 >Этот пример демонстрирует четыре основных понятия современных регулярных выражений:</para>
106 >Обратные ссылки</para
113 >, с которого начинается выражение - это утверждение, которое подтверждает совпадение только в том случае, если совпавшая цепочка символов начинается с новой строки.</para>
119 >(Петров|Иванов) рассказ(ыв)?ал</literal
120 > - это шаблоны. Первый представляет собой <emphasis
121 >символьный класс</emphasis
122 >, который совпадает либо с пробелом, либо с символом табуляции. Второй содержит вложенный шаблон, совпадающий со словами <literal
128 >, затем идёт проверка на точное совпадение со строкой <literal
130 >, потом ещё один вложенный шаблон, который определяет вхождение символов <literal
132 >, и, в самом конце, проверка на точное совпадение с символами <literal
139 > и символ вопроса после вложенного шаблона <literal
141 > - это кванторы. Первый можно трактовать следующим образом: <quote
142 >возможен повтор предыдущего символа от 0 до 4 раз</quote
143 >. Второй квантор действует аналогично, позволяя повторить стоящий перед ним вложенный шаблон 0 или 1 раз.</para>
146 >Все приложения, работающие с регулярными выражениями и поддерживающие <emphasis
147 >обратные ссылки</emphasis
148 >, при совпадении сохраняют всю строку и вложенные шаблоны в некоторой области памяти и предоставляют средства для получения этих значений. Поэтому мы можем получить всю совпавшую строку (при поиске в редакторе она обычно выделяется цветом) или, например, только фамилию.</para>
151 >Как вы могли убедиться на предыдущем примере, регулярные выражения - это очень эффективное средство поиска, позволяющее найти именно то, что вам нужно, без особых усилий.</para>
154 >В следующих разделах подробно рассмотрены шаблоны, символьные классы, утверждения, кванторы и обратные ссылки. В конце этой главы вы найдёте несколько полезных примеров.</para>
158 <sect1 id="regex-patterns">
164 >Шаблоны состоят из символов и символьных классов. Допускается вложенность, в этом случае вложенные шаблоны заключаются в круглые скобки.</para>
168 >Управляющие последовательности</title>
171 >И в шаблонах, и в символьных классах некоторые символы имеют специальное значение. Если вы хотите использовать эти символы при поиске именно как символы, нужно записать их определенным образом, чтобы анализатор регулярных выражений считал их обычными литералами.</para>
174 >Делается это очень просто, нужно всего лишь поставить перед таким символом бэк-слеш (<literal
180 >Анализатор регулярных выражений игнорирует обратную черту перед символами, которые не имеют специального значения в контексте; например, если вы вместо обычного символа <quote
182 > напишете <userinput
184 >, анализатор его воспримет просто как <quote
186 >. Таким образом, если вы не уверены, имеет ли символ специальное значение, можете спокойно ставить перед ним бэк-слеш.</para>
189 >Чтобы использовать обратную черту в качестве литерала, продублируйте его: <userinput
197 >Символьные классы и сокращения</title>
201 >Символьный класс</emphasis
202 > - это выражение, которое позволяет проверить один символ на принадлежность определенному набору символов. Чтобы использовать его в регулярных выражениях, нужно в квадратных скобках записать все верные символы или сокращенные классы, описанные ниже.</para>
205 >Простые символьные классы содержат один или несколько символов, например, <userinput
207 > (проверка на любой из символов <quote
214 >[0123456789]</userinput
215 > (проверка на любую цифру).</para>
218 >Поскольку буквы и цифры логически упорядоченны, вы можете сокращать классы, используя диапазоны: <userinput
220 > аналогично <userinput
224 > аналогично <userinput
225 >[0123456789]</userinput
226 >. Можно комбинировать диапазоны с обычным перечислением символов: <userinput
227 >[a-fynot1-38]</userinput
228 > (проверка на любой из символов <quote
259 >Чтобы проверить символ без учета регистра в любом случае (регулярное выражение может учитывать или не учитывать регистр символов), нужно написать примерно следующее: <userinput
264 >Можно создать <quote
266 > класс, который проверяет символ на <quote
268 > в заданный набор символов. Обычный символьный класс превращается в исключающий добавлением символа <quote
272 > перед набором символов: </para>
277 > - проверка на любой символ, <emphasis
288 >В дополнение к обычным литералам можно использовать следующие сокращения: <variablelist>
297 >Проверка на <acronym
299 >-символ звонка (BEL, 0x07).</para
310 >Проверка на <acronym
312 >-символ перевода страницы (FF, 0x0C).</para
323 >Проверка на символ перевода строки (LF, 0x0A, символ перехода на новую строку в Unix).</para
334 >Проверка на символ возврата каретки (CR, 0x0D).</para
345 >Проверка на символ горизонтальной табуляции (HT, 0x09)</para
356 >Проверка на символ вертикальной табуляции (VT, 0x0B).</para
367 >Проверка на символ в кодировке Unicode, соответствующий номеру hhhh (в пределах 0x0000-0xFFFF). \0ooo (первый символ - ноль) - проверка на символ в кодировке <acronym
369 >/Latin-1, соответствующий восьмеричному номеру ooo (в пределах 0-0377).</para
380 >Проверка на любой символ (включая переход на новую строку).</para
391 >Проверка на цифровой символ. Аналогично классу <literal
404 >Проверка на любой символ, не являющийся цифровым. Аналогично <literal
419 >Проверка на пробельный символ. Фактически аналогично классу <literal
432 >Проверка на любой символ, не являющийся пробельным. Фактически равнозначно <literal
434 > и аналогично <literal
447 >Проверка на любой алфавитно-цифровой символ (как вы поняли, сюда включаются все буквы и цифры). Подчеркивание (<literal
449 >) не входит в этот класс, в отличие от регулярных выражений perl. Это сокращение аналогично классу <literal
450 >[a-zA-Z0-9]</literal
462 >Проверка на любой символ, не являющийся алфавитно-цифровым. Аналогично классу <literal
463 >[^a-zA-Z0-9]</literal
476 >Аббревиатурные классы можно помещать в обычные классы; например, чтобы выполнить проверку на алфавитно-цифровой символ, точку или пробел, вы можете написать так: <userinput
483 >В текущей версии не поддерживается нотация классов POSIX (<userinput
484 >[:<class name>:]</userinput
490 >Символы со специальным значением в символьных классах</title>
493 >Ниже перечислены символы, имеющие специальное значение в определениях символьных классов (<quote
495 >). Для использования в качестве обычных литералов они должны быть предварены бэк-слешем.</para>
505 >Закрывает символьный класс. Этот символ должен быть предварен бэк-слешем, кроме тех случаев, когда стоит непосредственно в начале класса или сразу после символа <userinput
517 >Если стоит в начале, объявляет исключающий класс. Чтобы использовать как литерал в начале класса, нужно поставить бэк-слеш, иначе слеш не нужен.</para
528 >Определяет логический диапазон. Чтобы использовать в качестве литерала, всегда нужно ставить бэк-слеш.</para
535 > (обратная черта)</term>
538 >Спецсимвол (escape character). Чтобы использовать как литерал, продублируйте.</para
551 >Альтернативы: проверка на <quote
553 > нескольких шаблонов</title>
556 >Если вы хотите выполнить проверку на один (любой) шаблон из определенного набора, используйте альтернативы. Чтобы объявить альтернативу, нужно все шаблоны набора записать через пайп (<literal
561 >Например, чтобы найти любое из имён <quote
565 >, нужно использовать такое выражение: <userinput
566 >Вася|Петя</userinput
574 >Вложенные шаблоны</title>
578 >Вложенными</emphasis
579 > называются шаблоны, заключенные в круглые скобки. Они используются в разных целях:</para>
584 >Определение альтернатив</title>
587 >Используя вложенные шаблоны, вы можете группировать набор альтернатив внутри сложных шаблонов. Напомню, альтернативы разделяются символом пайп (<quote
592 >Например, чтобы найти одно из слов <quote
598 >, вы можете использовать шаблон <userinput
599 >int|float|double</userinput
600 >. Если же вы хотите найти одно из этих слов, за которым идут пробелы, а за ними какие-то символы, то вы должны оформить альтернативу как вложенный шаблон: <userinput
601 >(int|float|double)\s+\w+</userinput
609 >Захват совпавшего текста (обратные ссылки)</title>
612 >Чтобы создать обратную ссылку, оформите как вложенный шаблон ту часть выражения, которую нужно запомнить.</para>
615 >Например, если вы хотите найти два одинаковых слова, разделённых запятой и, возможно, пробелами, можно использовать такое выражение: <userinput
616 >(\w+),\s*\1</userinput
617 >. Вложенный шаблон <literal
619 > ищет цепочку алфавитно-цифровых символов, а всё выражение ищет ту же цепочку, за которой следует запятая, далее могут идти пробелы, а за ними точно такая же цепочка (строка <literal
621 > ссылается на <emphasis
622 >первый вложенный шаблон, заключенный в круглые скобки</emphasis
626 >See also <link linkend="backreferences"
627 >Back references</link
633 <sect3 id="lookahead-assertions">
635 >Просматривающие утверждения</title>
638 >Просматривающее утверждение - это вложенный шаблон, который начинается с символов <literal
645 >Например, чтобы найти слово <quote
647 >, за которым может следовать что угодно, кроме слова <quote
649 >, нужно составить такое выражение: <userinput
650 >Билл(?! Гейтс)</userinput
651 > (оно совпадет с <quote
654 >Билли хороший мальчик</quote
655 >, но не с именем известного магната).</para>
658 >Вложенные шаблоны, использующиеся в качестве утверждений, не запоминаются.</para>
661 >Смотрите также раздел <link linkend="assertions"
671 <sect2 id="special-characters-in-patterns">
673 >Символы со специальным значением в шаблонах</title>
676 >Следующие символы имеют специальное значение в шаблонах, поэтому, чтобы использовать их в качестве обычных символов, нужно впереди ставить обратную черту: <variablelist>
682 > (обратная черта)</term>
685 >С него должны начинаться все спецсимволы.</para
696 >Проверка на начало строки.</para
707 >Проверка на конец строки.</para
715 > (левая и правая круглые скобки)</term>
718 >Объявление вложенного шаблона.</para
726 > (левая и правая фигурные скобки)</term>
729 >Объявление числового квантора.</para
737 > (левая и правая квадратные скобки)</term>
740 >Объявление символьного класса.</para
748 > (вертикальная черта)</term>
751 >Логическое ИЛИ. Используется для разделения альтернатив.</para
763 >один или более</quote
776 >ноль или более</quote
785 > (знак вопроса)</term>
788 >Необязательный символ. Можно считать его квантором <quote
789 >ноль или один</quote
802 <sect1 id="quantifiers">
809 > выполняют проверку на определенное количество повторений символа, шаблона или символьного класса.</para>
812 >Кванторы записываются в фигурных скобках (<literal
816 >). Общий вид квантора: <literal
817 >{[минимальное-количество-совпадений][,[максимальное-количество-совпадений]]}</literal
821 >Использование кванторов лучше пояснить на примерах: <variablelist>
830 >Ровно одно появление</para
841 >Ноль или одно появление</para
852 >То же самое, но набирать меньше ;)</para
863 >Как минимум 5 повторений, максимум - 10.</para
874 >Как минимум 5 повторений (без верхней границы).</para
883 >Также определены несколько сокращений: <variablelist>
894 >, найти любое количество повторений (вплоть до нуля повторений).</para
907 >, как минимум одно появление.</para
915 > (знак вопроса)</term>
920 >, ноль или одно появление.</para
934 >Используя кванторы без ограничений максимума, регулярное выражение захватывает строку по максимуму, такое поведение называется <emphasis
939 >Современные анализаторы позволяют определять как жадные, так и нежадные регулярные выражения. В основном, это проявляется в соответствующих элементах графического интерфейса, например, в диалоге поиска может быть опция <quote
940 >Минимальное совпадение</quote
947 >Примеры использования</title>
950 >Здесь приведено несколько примеров использования кванторов.</para>
957 >^\d{4,5}\s</userinput
965 >, но не совпадет ни с <quote
980 >Проверка на один или более пробельных символов.</para
993 > и с подстрокой <quote
1013 ><closeditem/></quote
1017 ><openitem></quote
1028 <sect1 id="assertions">
1030 >Утверждения</title>
1034 >Утверждения</emphasis
1035 > накладывают дополнительные условия на проверку регулярного выражения.</para>
1038 >Утверждение не проверяет символы, скорее, оно анализирует совпавшую строку перед тем как подтвердить совпадение. Например, утверждение <emphasis
1039 >граница слова</emphasis
1040 > не пытается найти символ-разделитель слов, наоборот, оно проверяет, что в данной позиции нет алфавитно-цифрового символа. Это означает, что утверждение будет верно даже в случае отсутствия символа-разделителя, например, в конце строки поиска.</para>
1043 >Некоторые утверждения являются шаблонами, но они лишь проверяют, есть или нет в данном месте строки совпадение заданному шаблону, не включая его в конечный результат.</para>
1046 >Регулярные выражения, описанные в этом руководстве, поддерживают следующие утверждения: <variablelist>
1053 > (начало строки)</term
1057 >Проверка на начало строки.</para
1059 >Выражение <userinput
1064 >Петр, здравствуйте!</quote
1065 >, но не в строке <quote
1066 >Здравствуйте, Петр!</quote
1075 > (конец строки)</term>
1078 >Проверка на конец строки поиска.</para>
1081 >Выражение <userinput
1083 > совпадет с последним <quote
1086 >- Ты не сделаешь этого! - А ты?</quote
1087 >, но не совпадет ни с какой частью строки <quote
1088 >Ты не сделал этого, так?</quote
1098 > (граница слова)</term>
1101 >Проверяет, есть ли в данном месте с одной стороны алфавитно-цифровой символ, а с другой - не алфавитно-цифровой (необязательно разделитель!).</para>
1103 >Это утверждение используется для поиска границ слов; например, можно использовать два таких утверждения, чтобы найти целое слово. Выражение <userinput
1105 > совпадет с отдельным словом <quote
1108 >Он выпал из этого окна, хорошо хоть, что тут низко</quote
1109 >, но не совпадет с <quote
1122 > (нет границы слова)</term>
1125 >Действие этого утверждения обратно утверждению <quote
1129 >Это значит, что данное утверждение будет совпадать, например, в середине слова: выражение <userinput
1144 >(?=ШАБЛОН)</userinput
1145 > (подтверждающий просмотр)</term>
1148 >Просматривающие утверждения действуют аналогично обычным шаблонам, с той лишь разницей, что текст, совпавший (или не совпавший, в зависимости от типа просмотра) с утверждением, не будет включен в результирующее совпадение. Подтверждающий просмотр проверяет текст на предмет совпадения с <emphasis
1150 > утверждения.</para>
1152 >Выражение <userinput
1153 >программ(?=\w)</userinput
1158 >, но не во фразе <quote
1159 >Он написал много хороших программ!</quote
1167 >(?!ШАБЛОН)</userinput
1168 > (отрицающий просмотр)</term>
1172 >Отрицающий просмотр проверяет текст на предмет несовпадения с <emphasis
1176 >Выражение <userinput
1177 >const \w+\b(?!\s*&)</userinput
1181 >const char* foo</quote
1182 >, но не совпадет с <quote
1183 >const QString</quote
1185 >const QString& bar</quote
1188 > совпадает с шаблоном отрицающего просмотра.</para>
1198 <!-- TODO sect1 id="backreferences">
1201 >Back References</title>