Регулярные выражения PCRE, Perl, Posix, Bre, Ere. Что это, и как ими пользоваться

Описание стандартов

Регулярные выражения стандарта POSIX изначально были придуманы для unix систем. Именно этот стандарт можно встретить в большинстве офисных программ. В свою очередь регулярные выражения POSIX делятся на категории: BRE (Basic Regular Expressions) и ERE (Extended Regular Expressions). POSIX считается устаревшив стандартом.

Регулярные выражения Perl — изначально включены в сам язык программирования Perl.

Регулярные выражения библиотеки PCRE (Perl Compatible Regular Expressions) — Perl совместимые выражения, основаны на Perl, но имеют отличия. Используются в различных языках программирования.

Синтаксис PCRE

Разделители

Одно из отличий регулярных выражений PCRE от стандарта Posix в том, что шаблон надо обрамлять разделителями.

Разделителем может быть любой символ не являющийся буквой, цифрой, обратной косой чертой или каким-либо пробельным символом.

Подробнее

Часто используемыми разделителями являются косые черты (/), знаки решетки (#) и тильды (~). Ниже представлены примеры шаблонов с корректными разделителями.

/foo bar/
#^[^0-9]$#
+php+
%[a-zA-Z0-9_-]%

(this [is] a (pattern))
{this [is] a (pattern)}
[this [is] a (pattern)]
<this [is] a (pattern)>

Разделители в виде скобок не нужно экранировать, если они также используются как метасимволы в шаблоне, но как и с другими разделителями их нужно экранировать, если они используются непосредственно как символы.

Если необходимо использовать разделитель внутри шаблона, его нужно проэкранировать с помощью обратной косой черты. 

Символьные классы

Символьные классы — группы символов заключенные в квадратные скобки.

Предопределенные символьные классы

Текстовая запись Символьная запись Perl  
[:alnum:] [A-Za-z0-9]   цифры, символы верхнего и нижнего регистра
  [A-Za-z0-9_] \w цифры, символы верхнего, нижнего регистра и "_"
  [^A-Za-z0-9_] \W не цифры, символы верхнего, нижнего регистра и "_"
[:alpha:] [A-Za-z]   символы верхнего и нижнего регистра
[:ascii:]     символы с кодами 0 - 127
[:blank:] [ \t]   только пробел или символ табуляции
[:cntrl:] [\x00-\x1F\x7F]   управляющие символы
[:digit:] [0-9] \d десятичные цифры
  [^0-9] \D не цифры
[:graph:] [:alnum:] ∪ [:punct:]   печатные символы, исключая пробел
[:lower:] [a-z]   строчные буквы (символы нижнего регистра)
[:print:] [\x20-\x7E]   печатные символы, включая пробел
[:punct:] [.,!?:…]   знаки пунктуации (печатные символы, исключая буквы и цифры)
[:space:] [ \t\n\r\f\v] \s пробельные символы
  [^ \t\n\r\f\v] \S не пробельные символы
[:upper:] [A-Z]   прописные буквы (символы верхнего регистра)
[:word:]   \w символы «слова» 
[:xdigit:] [0-9A-Fa-f]   шестнадцатеричные цифры

Метасимволы

Метасимволы — символы интерпретирующиеся особым образом: обозначающие любой знак, начало или конец строки и т.п.

Существуют два различных набора метасимволов: те, которые используются внутри квадратных скобок, и те, которые используются вне квадратных скобок (в символьных классах). 

Метасимволы вне квадратных скобок
Метасимволы внутри квадратных скобок (символьные классы)
Метасимволы вне квадратных скобок
Метасимвол Описание
\ общий экранирующий символ, допускающий несколько вариантов применения
^ декларирует начало данных (или строки в многострочном режиме)
$ декларирует конец данных или до завершения строки (или окончание строки в многострочном режиме)
. соответствует любому символу, кроме перевода строки (по умолчанию)
[ начало описания символьного класса
] конец описания символьного класса
| начало ветки условного выбора
( начало подмаски
) конец подмаски
? расширяет смысл метасимвола (, является также квантификатором, означающим 0 или 1 вхождение, также преобразует жадные квантификаторы в ленивые (смотрите повторение))
* квантификатор, означающий 0 или более вхождений
+ квантификатор, означающий 1 или более вхождений
{ начало количественного квантификатора
} конец количественного квантификатора

Часть шаблона, заключенная в квадратные скобки называется символьным классом.

Метасимволы внутри квадратных скобок (символьные классы)
Метасимвол Описание
\ общий экранирующий символ
^ означает отрицание класса, допустим только в начале класса
- означает символьный интервал

Экранирующие последовательности

Если в шаблоне надо использовать символ который относится к числу метасимволов, его надо предварительно заэкранировать поставив перед ним знак «\».

Также у обратного слеша есть другие применения, в группе с другими символами он приобретает дополнительные свойства:

Использовать непечатные символы
Указывать тип символов
Определять месторасположения позиций

 Позволяет использовать непечатные символы в видимой форме в описании шаблона.

\a символ оповещения, сигнал, (BEL, шестнадцатеричный код 07)
\cx «Ctrl+x», где x — произвольный символ
\e escape (шестнадцатеричный код 1B)
\f разрыв страницы (шестнадцатеричный код 0C)
\n перевод строки (шестнадцатеричный код 0A)
\p{xx} символ со свойством xx
\P{xx} символ без свойства xx
\r возврат каретки (шестнадцатеричный код 0D)
\R разрыв строки: совпадает с \n, \r и \r\n
\t табуляция (шестнадцатеричный код 09)
\xhh символ с шестнадцатеричным кодом hh
\tdd символ с восьмеричным кодом tdd, либо ссылка на подмаску

Позволяет указывать общий тип символов 

\d любая десятичная цифра
\D любой символ, кроме десятичной цифры
\h любой горизонтальный пробельный символ (начиная с версии PHP 5.2.4)
\H любой символ, не являющийся горизонтальным пробельным символом (начиная с версии PHP 5.2.4)
\s любой пробельный символ
\S любой непробельный символ
\v любой вертикальный пробельный символ (начиная с версии PHP 5.2.4)
\V любой символ, не являющийся вертикальным пробельным символом (начиная с версии PHP 5.2.4)
\w Любой символ, образующий «слово»
\W Любой символ, не образующий «слово»

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

\b граница слова
\B не является границей слова
\A начало данных (независимо от многострочного режима)
\Z конец данных либо позиция перед последним переводом строки (независимо от многострочного режима)
\z конец данных (независимо от многострочного режима)
\G первая совпадающая позиция в строке

Якоря

Якоря — символы позволяющие задать некий интервал шаблона, начало и конец какого-либо отрезка кода.

Вне символьного класса

^ Символ обозначающий начало строки
$ Символ обозначающий конец строки

Если в шаблоне несколько вариантов альтернативного выбора, то каждый из этих символов должен быть указан в каждой из альтернатив, т.к. они будут якорем начала и конца альтернативной группы. 

Альтернативный выбор, оператор «или»

| — оператор или

Модификаторы шаблонов

i PCRE_CASELESS Если этот модификатор используется, символы в шаблоне соответствуют символам как верхнего, так и нижнего регистра
m PCRE_MULTILINE По умолчанию, PCRE обрабатывает данные как однострочную символьную строку (даже если она содержит несколько разделителей строк). Метасимвол начала строки '^' соответствует только началу обрабатываемого текста, в то время как метасимвол "конец строки" '$' соответствует концу текста, либо позиции перед завершающим текст переводом строки (в случае, если модификатор D не установлен). В Perl ситуация полностью аналогична. Если этот модификатор используется, метасимволы "начало строки" и "конец строки" также соответствуют позициям перед произвольным символом перевода и строки и, соответственно, после, как и в самом начале и в самом конце строки. Это соответствует Perl-модификатору /m. В случае, если обрабатываемый текст не содержит символов перевода строки, либо шаблон не содержит метасимволов '^' или '$', данный модификатор не имеет никакого эффекта.
s PCRE_DOTALL Если данный модификатор используется, метасимвол «точка» в шаблоне соответствует всем символам, включая перевод строк. Без него — всем, за исключением переводов строк
x PCRE_EXTENDED Если используется данный модификатор, неэкранированные пробелы, символы табуляции и пустой строки будут проигнорированы в шаблоне, если они не являются частью символьного класса. Также игнорируются все символы между неэкранированным символом '#' и символом перевода строки 
U PCRE_UNGREEDY инвертирует жадность квантификаторов
X PCRE_EXTRA включает дополнительную функциональность PCRE, которая не совместима с Perl: любой обратный слеш в шаблоне, за которым следует символ, не имеющий специального значения, приводят к ошибке
J PCRE_INFO_JCHANGED Модификатор (?J) меняет значение локальной опции PCRE_DUPNAMES - подшаблоны могут иметь одинаковые имена
u PCRE_UTF8 включает дополнительную функциональность PCRE, которая не совместима с Perl: шаблон и целевая строка обрабатываются как UTF-8 строки
S   В случае, если планируется многократно использовать шаблон, имеет смысл потратить немного больше времени на его анализ, чтобы уменьшить время его выполнения. В случае, если данный модификатор используется, проводится дополнительный анализ шаблона. В настоящем это имеет смысл только для «незаякоренных» шаблонов, не начинающихся с какого-либо определенного символа
D PCRE_DOLLAR_ENDONLY Если используется данный модификатор, метасимвол $ в шаблоне соответствует только окончанию обрабатываемых данных. Без этого модификатора метасимвол $ соответствует также позиции перед последним символом, в случае, если им является перевод строки (но не распространяется на любые другие переводы строк). Данный модификатор игнорируется, если используется модификатор m
A PCRE_ANCHORED Если используется данный модификатор, соответствие шаблону будет достигаться только в том случае, если он «заякорен», т.е. соответствует началу строки, в которой производится поиск

Примеры

Запись ссылки 

<a.*?href=*.?>(.+?)</a>

Замена обрамляющих тегов у текста

/* Выбираем текст */
<td>(.*)</td> // 1 строка
<td>(.*)</td> // 2 строка

/* Заменяем на выбранный текст */
<p>(\1)</p> // 1 текст
<p>(\2)</p> // 2 текст