Иллюстрированный самоучитель по Perl

       

Расширенный синтаксис регулярных выражений


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

?:pattern

Конструкция относится к классу конструкций общего вида (?...), добавляющих новые возможности для задания образцов за счет расширения синтаксиса регулярного выражения, а не за счет введения новых метасимволов или метапоследовательностей. Символ, следующий за символом "?", опреде- , ляет функцию, выполняемую данной синтаксической конструкцией. В на^ стоящее время определены около десяти расширенных конструкций регулярного выражения, большая часть которых рассмотрена в данном разделе. Оставшиеся конструкции, на наш взгляд, не являются необходимыми для первоначального знакомства с языком.

(?#text)

Текст после символа tt и до закрывающей скобки ), комментарий, игнорируется интерпретатором и используется для добавления непосредственно в регулярное выражение.

(?:pattern)

(?imsx-imsx:pattern)

Использовать скобки только для группирования элементов без создания обратных ссылок. Символы imsx-imsx между вопросительным знаком и двоеточием интерпретируются как флаги, модифицирующие функцию данного выражения (см. ниже).

(?=pattern)

Следующий фрагмент в тексте должен соответствовать образцу pattern. Обычно образец для операций поиска или замены задается при помощи регулярного выражения. Результатом операции поиска является фрагмент, соответствующий образцу, который сохраняется в специальной переменной $&. Конструкция (?=pattern) в составе регулярного выражения позволяет задать условие поиска, не включая найденный фрагмент, соответствующий образцу pattern, в результат, сохраняемый в переменной $&. Конструкция (?=pattern) в регулярном выражении задает условие, что следующий фрагмент текста должен удовлетворять образцу pattern. Обращаем внимание на слово следующий. Данная конструкция неприменима для задания условия, что предыдущий фрагмент текста должен соответствовать заданному образцу. Например, образцу /b+(?=с+)/ соответствует часть строки, состоящая из одной или более литер ь, за которыми следуют одна или более литер с, причем найденный фрагмент текста будет содержать только последовательность литер ь без последовательности литер с.




Рассмотрим строку



$str = "aaabbbcccddd";

В результате операции поиска

$str =~ m/b+(?=c+)/;

будут сохранены следующие значения в специальных переменных:

$ ч — ааа $& - bbb $' — cccddd

Если в операции поиска указать образец /b+с+/, то значения специальных переменных будут следующими:

$" — ааа $& — bbbссс $' - ddd

В свою очередь, операция поиска по образцу / (?=b+) с+/ в нашем примере не даст результата. Данный образец задает условие, что следующий фрагмент текста должен содержать непустую последовательность литер ь. В нашей строке такой -фрагмент будет найден (это фрагмент bbb>, но не будет включен в результат поиска. Следующий фрагмент, в соответствии с образцом, должен представлять непустую последовательность литер с, но в нашем случае этого соответствия не будет, так как мы остановились перед фрагментом ььь, не включив его в результат, и поэтому следующим фрагментом будет bbb, а не ссс.

Конструкцию (?=pattern) будем называть регулярным выражением с положительным постусловием.

(?!pattern)

Конструкция (? [pattern) в регулярном выражении задает условие, что следующий фрагмент текста не должен удовлетворять образцу pattern. Найденный фрагмент не запоминается в переменной $&. Например, результат операции поиска

$str =~ m/b+(?!c+)/;

в рассмотренной выше строке $str будет зафиксирован в следующих значениях специальных переменных:

$' — ааа

$& - bb

$' — bcccddd

Найденная подстрока соответствует образцу: она состоит из двух литер ьь, за которыми не следует последовательность литер с.

По аналогии с предыдущей данную конструкцию назовем регулярным выражением с отрицательным постусловием.

(?<=pattern)

Конструкция (?<=pattern) в регулярном выражении задает условие, что предыдущий фрагмент текста должен удовлетворять образцу pattern. Найденный фрагмент не запоминается в переменной $&. Образец pattern должен иметь фиксированную длину, т. е. не содержать множителей.

В нашем примере в результате операции поиска

$str =~ m/(?<=b)b+/;



значения специальных переменных будут распределены следующим образом:

$' — aaab

$& - bb

$' - cccddd I

Данную конструкцию назовем регулярным выражением с положительным предусловием. _/

(?<!pattern)

Конструкция (?<! pattern) в регулярном выражении задает условие, что предыдущий фрагмент текста не должен удовлетворять образцу pattern. Найденный фрагмент не запоминается в переменной $&. Образец pattern должен иметь фиксированную длину, т. е. не содержать множителей.

В нашем примере в результате операции поиска

$str =~ m/(?<!b)c+/;

специальные переменные получат следующие значения:

$' — aaabbbc $& — ее $' - ddd

Данную конструкцию будем называть регулярным выражением с отрицательным предусловием.

(?imsx-imsx)

Задание флагов операции сопоставления с образцом осуществляется в самом образце. Флаги модифицируют выполнение операции и обычно являются частью синтаксиса самой операции. Расширенная конструкция (?imsx-imsx) позволяет задать флаги операции внутри самого образца. Эта возможность может быть полезной, например, в таблицах, когда разные элементы таблицы требуется по-разному сопоставлять с заданным образцом, например, некоторые элементы — с учетом регистра, другие — без учета. Допустимыми являются следующие флаги.

  • i — поиск без учета регистра;


  • dm — строка трактуется как мульти-строка, состоящая из нескольких строк, разделенных символом новой строки;


  • s — строка трактуется как одна строка, в этом случае метасимволу "." соответствует любой одиночный символ, включая символ новой строки;


  • х — разрешается использовать в образцах пробелы и комментарии. При использовании флага х пробелы в образцах игнорируются. Признаком комментария является символ #, как и в основном тексте Peri-программы. Пробелы позволяют сделать образец более читаемым.


  • Одна из литер i, m, s, x после знака "-" обозначает отмену соответствующего флага.

    При помощи данной расширенной конструкции можно задать, например, следующий образец

    /(?ix) peri # игнорирование регистра при поиске/

    Флаг i предписывает не учитывать регистр в операциях сопоставления с образцом, так что образцу будет соответствовать и слово peri, и слово Perl. Флаг х позволяет выделить слово "peri" пробелами и использовать в образце комментарий. И пробелы, и комментарий не будут учитываться в операции сопоставления с образцом.




    Содержание раздела