На этом шаге мы рассмотрим использование расширенного синтаксиса регулярных выражений.
В предыдущих шагах мы использовали скобки для группирования нескольких элементов регулярного выражения в один элемент. Побочным эффектом данной операции является запоминание найденного фрагмента текста, соответствующего образцу, заключенному в скобки, в специальной переменной. Если скобки используются только для группирования элементов регулярного выражения, то найденный фрагмент текста можно не запоминать. Для этого после открывающей скобки "(" следует поместить конструкцию "?:", например, в случае задания альтернативы /(?:Perl|perl)/:
?:pattern
Конструкция относится к классу конструкций общего вида (?...), добавляющих новые возможности для задания образцов за счет расширения синтаксиса регулярного выражения, а не за счет введения новых метасимволов или метапоследовательностей. Символ, следующий за символом "?", определяет функцию, выполняемую данной синтаксической конструкцией. В настоящее время определены около десяти расширенных конструкций регулярного выражения, большая часть которых рассмотрена на данном шаге. Оставшиеся конструкции, на наш взгляд, не являются необходимыми для первоначального знакомства с языком.
(?#text)
Текст после символа # и до закрывающей скобки ), комментарий, игнорируется интерпретатором и используется для добавления непосредственно в регулярное выражение.
(?:pattern) (?imsx-imsx:pattern)
Использовать скобки только для группирования элементов без создания обратных ссылок. Символы imsx-imsx между вопросительным знаком и двоеточием интерпретируются как флаги, модифицирующие функцию данного выражения (см. ниже).
(?=pattern)
Следующий фрагмент в тексте должен соответствовать образцу pattern. Обычно образец для операций поиска или замены задается при помощи регулярного выражения. Результатом операции поиска является фрагмент, соответствующий образцу, который сохраняется в специальной переменной $&. Конструкция (?=pattern) в составе регулярного выражения позволяет задать условие поиска, не включая найденный фрагмент, соответствующий образцу pattern, в результат, сохраняемый в переменной $&. Конструкция (?=pattern) в регулярном выражении задает условие, что следующий фрагмент текста должен удовлетворять образцу pattern. Обращаем внимание на слово следующий. Данная конструкция неприменима для задания условия, что предыдущий фрагмент текста должен соответствовать заданному образцу. Например, образцу /b+(?=с+)/ соответствует часть строки, состоящая из одной или более литер b, за которыми следуют одна или более литер c, причем найденный фрагмент текста будет содержать только последовательность литер b без последовательности литер c.
$str = "aaabbbcccddd";
$str =~ m/b+(?=c+)/;
$` - ааа $& - bbb $' - cccddd
$` - ааа $& - bbbccc $' - ddd
В свою очередь, операция поиска по образцу / (?=b+) с+/ в нашем примере не даст результата. Данный образец задает условие, что следующий фрагмент текста должен содержать непустую последовательность литер b. В нашей строке такой фрагмент будет найден (это фрагмент bbb), но не будет включен в результат поиска. Следующий фрагмент, в соответствии с образцом, должен представлять непустую последовательность литер c, но в нашем случае этого соответствия не будет, так как мы остановились перед фрагментом bbb, не включив его в результат, и поэтому следующим фрагментом будет bbb, а не ccc.
Конструкцию (?=pattern) будем называть регулярным выражением с положительным постусловием.
(?!pattern)
$str =~ b/m+(?!c+)/;
$` - ааа $& - bb $' - bcccddd
Найденная подстрока соответствует образцу: она состоит из двух литер bb, за которыми не следует последовательность литер c.
По аналогии с предыдущей данную конструкцию назовем регулярным выражением с отрицательным постусловием.
(?<=pattern)
Конструкция (?<=pattern) в регулярном выражении задает условие, что предыдущий фрагмент текста должен удовлетворять образцу pattern. Найденный фрагмент не запоминается в переменной $&. Образец pattern должен иметь фиксированную длину, т. е. не содержать множителей.
В нашем примере в результате операции поиска
$str =~ m/(?<=b)b+/;
$` - aaab $& - bb $' - cccddd
Данную конструкцию назовем регулярным выражением с положительным предусловием.
(?<!pattern)
Конструкция (?<!pattern) в регулярном выражении задает условие, что предыдущий фрагмент текста не должен удовлетворять образцу pattern. Найденный фрагмент не запоминается в переменной $&. Образец pattern должен иметь фиксированную длину, т.е. не содержать множителей.
В нашем примере в результате операции поиска
$str =~ m/(?<!b)c+/;
$` - aaabbbc $& - cc $' - ddd
Данную конструкцию будем называть регулярным выражением с отрицательным предусловием.
(?imsx-imsx)
Задание флагов операции сопоставления с образцом осуществляется в самом образце. Флаги модифицируют выполнение операции и обычно являются частью синтаксиса самой операции. Расширенная конструкция (?imsx-imsx) позволяет задать флаги операции внутри самого образца. Эта возможность может быть полезной, например, в таблицах, когда разные элементы таблицы требуется по-разному сопоставлять с заданным образцом, например, некоторые элементы - с учетом регистра, другие - без учета. Допустимыми являются следующие флаги.
Одна из литер i, m, s, x после знака "-" обозначает отмену соответствующего флага.
При помощи данной расширенной конструкции можно задать, например, следующий образец
/(?ix) perl # игнорирование регистра при поиске/
Флаг i предписывает не учитывать регистр в операциях сопоставления с образцом, так что образцу будет соответствовать и слово perl, и слово Perl. Флаг х позволяет выделить слово "perl" пробелами и использовать в образце комментарий. И пробелы, и комментарий не будут учитываться в операции сопоставления с образцом.
На следующем шаге мы приведем сводку результатов по изученному материалу.