Регулярные выражения

Регулярные выражения ("регэкспы", от англ. Regular Expressions) - мощное средство составления шаблонов, с помощью которых в заданном тексте может проводиться поиск и сопоставление символов любой сложности.

Как составляется такой шаблон? Для этого используются специальные символы, метасимволы и классы (наборы) символов. Регулярное выражение - это простая строка и любые символы в этой строке, которые не являются специальными (зарезервированными), считаются обычными символами.

Служебные символы делятся на три класса:

Любое выражение можно сгруппировать (заключить в скобки) и применить оператор ко всей группе.

Синтаксис регулярных выражений, использующийся в nnCron, совпадает с синтаксисом регулярных выражений языка Perl. Небольшие отличия есть только в некоторых расширенных специфических операторах.



Синтаксис

Все регэкспы должны заключаться в прямые слэши (/.../). После конечного слэша могут идти параметры:

/.../i - не различать регистр.
/.../x - игнорировать пробелы и переводы строк (для удобства).
/.../s - считать регэксп одной единственной строкой (трактовать спецсимвол . (точка) как "любой символ, в том числе и символ перевода строки").

Примеры:

\ совпадет только со словом 'Valery'
/Valery/
\ совпадет со словами 'VALERY', 'valery', 'Valery' и т. д.
/Valery/i 
\ совпадет с 'foobar', 'foobar barfoo'
/foobar/
\ совпадет с 'foobar', 'FOOBAR', 'foobar and two other foos'
/ FOO bar /ix
\ совпадет с 'Valery%crlf%Kondakoff'
/Valery.*Kondakoff/s

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


Спецсимволы


^ Начало строки
$ Конец строки
. Любой символ кроме переводов строки (без параметра /.../s)
[ ... ]

Любой из перечисленного набора символов. Внутри квадратных скобок не работают другие операторы, но можно пользоваться метасимволами.
С помощью дефиса можно указывать наборы символов: от первого до последнего. Например, [a-f] означает любую букву из числа a, b, c, d, e, f.

[^ ... ] Ни один из перечисленного набора символов. Внутри квадратных скобок не работают другие операторы, но можно пользоваться метасимволами.
С помощью дефиса можно указывать наборы символов: от первого до последнего. Например, [^0-9] означает любой символы, кроме 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
\#

Следующий за слэшем символ # (кроме a-z и 0-9).
Например, \\ означает символ \, \. означает символ . (точка), \$ означает символ $ и т. д.

\b Начало слова
\B Конец слова
\xNN NN - шестнадцатеричный код ASCII-символа (\x20 - пробел, \x4A - J, \x6A - j и т. д.)
\n 0x10 (lf)
\r 0x13 (cr)
\t 0x09 (tab)
\s Пробел (tab/space/cr/lf)
\S Не пробел
\w Символ слова (буквы, цифры, _)
\W Символ не-слова
\d Число
\D Не число
\u Символ в верхнем регистре
\l В нижнем

Примеры:

\ совпадает со словом 'help' с точкой
/help\./
\ совпадает со словами 'cats', 'cars' и т. д.
/ca.s/
\ совпадает со словами 'testing', 'tester', но не 'the test'
/^test/
\ совпадает с выражением 'see me', но не с 'meter' или 'me and you'
/me$/
\ совпадает с одной (латинской) гласной буквой
/[aeiou]/
\ совпадает с одной буквой или цифрой
/[a-z0-9]/
\ совпадает с 'footer', 'footing', 'a foot', но не с 'afoot' /\bfoot/ \ совпадает с 'afoot', 'foot.' (точка не считается частью слова) \ не совпадает с 'footing' /foot\B/ \ совпадает со словом 'foot' целиком /\bfoot\B/ \ совпадает со словами 'q2w', 'r5t' и т. д. /\D\d\D/

Расширенные спецсимволы

В отличии от обычных символов эти классы не совместимы с перловыми:

\N Ссылка внутри регэкспа на его же разобранную скобку, число N - номер нужной группы (скобки). Этот оператор работает с некоторыми ограничениями на тип ссылаемого блока - он работает, только если в ссылаемой скобке нет операторов повторения.

Пример:

\ совпадает с фразами 'man to man', '
\ hand to hand', '100 to 100' и т. д.
(\b\w+\B) to \1

Операторы

Операторы не могут применяться сами по себе, без указания символа, на который они действуют. Оператор действует на определенный перед ним символ (мета или обычный). Если какое-то выражение заключено в скобки, после которых стоит оператор, то он действует на всю скобку.

( ... ) Сгруппировать символы в один паттерн и запомнить
| Предыдущий или следующий паттерн (логическое "ИЛИ")
* Ноль или больше раз
+ Один или больше раз
? 0 или 1 раз предыдущая маска
{n} Повторять n раз
{n,} Повторять n или больше раз
{n,m} Повторять от n до m раз

Примеры:

\ совпадает со словами 'cat' или 'mouse'
/(cat)|(mouse)/
\ совпадает со словами 'dogs', 'doggie'
/dog(s|gie)/
\ совпадает с 'ma', 'maaa', 'maaaaaaa'
/ma+/
\ совпадает с 'm', 'maaa'
/ma*/
\ совпадает с 'yada yada yada'
/(yada ){2,}/
\ совпадает с 'fooandbar', 'foobar'
/foo(and)?bar/

Если после оператора добавить ?, то он превращается из жадного в нежадный. К примеру жадный * будет нежадным после замены его на *?. Жадные операторы производят максимальный захват в строке, а нежадные захватывают по минимуму.


Расширенные операторы

?#N Это оператор "просмотра назад". N - число символов для просмотра.
?~N Отрицание просмотра назад.
?= Просмотр вперед.
?! Отрицание просмотра вперед.

Заметьте, что хотя последние два оператора существуют и в перле, в нем они записываются в виде (?=foobar). В nnCron оператор выглядит как (foobar)?=.

Примеры:

\ совпадет с любым словом, после которого знак табуляции
\ при этом сам знак табуляции не войдет в число совпавших символов
/\w+(\t)?=/
\ совпадет с любым появлением 'foo', которое не продолжается 'bar'
/foo(bar)?!/
\ совпадет с любым появлением 'bar', которому предшествует 'foo'
/(foo)?#3bar/ 

Еще немного примеров:

\ совпадет с "foobar", "bar"
/(foo)?bar/
\ совпадет _только_ с "foobar"
/^foobar$/
\ совпадет с "foobar", "for", "far"
/f[obar]+r/
\ задает любое число с десятичной запятой
/([\d\.])+/
\ совпадет с "foofoofoobarfoobar", "bar"
/((foo)|(bar))+/