Вся работа колорера основывается на использовании регулярных выражений - они являются базовым механизмом для задания универсальных синтаксических правил разбора, которыми руководствуется колорер. Сами по себе регулярные выражения довольно независимы и широко применяются; они позволяют описывать шаблоны для распознавания символьных данных - проще говоря регулярное выражение позволяет описать некий обобщенный класс строки символов определенного формата и ответить на вопрос принадлежит ли этому классу какая-то конкретная строка.
Каким образом задается этот шаблон? Для этого используются различные специальные символы, метасимволы и классы(наборы) символов. Само регулярное выражение является обычной строкой и любые символы в этой строке, которые не являются специальными(зарезервированными), считаются обычными символами. Служебные символы делятся на три класса: первый означает какой-либо класс(набор) символов (к примеру \w означает любую букву), второй в отличии от первого не имеет длины (например ^ - начало строки, \b - граница слова). Третий класс - это операторы. Операторы применяются к метасимволам, к обычным символам или к другим операторам. Любое выражение можно сгруппировать (заключить в скобки) и применить оператор ко всей группе.
Регулярные выражения колорера в стандартном синтаксисе совпадают с языком perl и различаются только по расширенным спецефическим операторам.
Все регэкспы должны заключаться в слэши /.../ После конечного слэша могут идти параметры:
Далее в регэкспе последовательно сравнивается каждый символ с проверяемой строкой. Все, что не является указанными ниже спецсимволами или операторами, воспринимается, как обычный символ, рассматриваемый на совпадение.
^ Начало строки $ Конец строки . Любой символ кроме переводов строки (без параметра //s) [ ] Любой из перечисленного набора символов [^ ] Ни один из набора В этих двух паттернах другие операторы не работают, но можно пользоваться другими метасимволами, и вариантом a-z , определяющим набор символов от первого до второго. \# Следующий за слешем символ '#' (кроме a-z и 1-9) - квотирование \b Начало слова \B Конец слова \xNN NN - ASCII символ (hex) \n 0x10 (lf) \r 0x13 (cr) \t 0x09 (tab) \s Пробел (tab/space/cr/lf) \S Не пробел \w Символ слова (буквы, цифры, _) \W Символ не-слова \d Число \D Не число \u Символ в верхнем регистре \l В нижнем
В отличии от обычных символов эти классы не совместимы с перловыми:
\c Означает 'не-слово-до...' \N Ссылка внутри регэкспа на его же разобранную скобку, число N - номер нужной группы (скобки). Этот оператор работает с некоторыми ограничениями на тип ссылаемого блока - он работает, только если в ссылаемой скобке нет операторов повторения.А эти операторы спецефичны для колорера и могут отключаться при компиляции класса cregexp:
#ifdef COLORERMODE ~ Ловит начало предыдущей схемы (конец блока start). \m Смена начала регэкспа. \M Смена конца регэкспа. \yN Ссылка в тэге End на тэг Start. Число N - номер нужной подгруппы. \YN Аналогично предыдущему - но совпадение должно быть с точностью до регистра символов. #endif
Операторы не могу применяться просто так - без всего. Оператор действует на определенный перед ним символ(мета или обычный). Если какое-то выражение заключено в скобки, после которых стоит оператор, он действует на всю скобку.
( ) Сгруппировать символы в один паттерн и запомнить | Предыдущий или следующий паттерн * Ноль или больше раз + Один или больше раз ? 0 или 1 раз предыдущая маска {n} Повторять n раз {n,} Повторять n или больше раз {n,m} Повторять от n до m разЕсли после оператора добавить ?, то он превращается из жадного в нежадный. К примеру жадный * будет нежадным после замены его на *? Жадные операторы производят максимальный захват в строке, а нежадные захватывают по минимуму.
?#N Это оператор 'просмотра назад'. N - число символов для просмотра. ?~N Отрицание просмотра назад. ?= Просмотр вперед. ?! Отрицание просмотра вперед.
Заметьте, что хотя последние два оператора существуют и в перле,
в нем они записываются в виде (?=foobar)
. В случае же колорера
оператор выглядит как (foobar)?=
/foobar/ совпадет с "foobar", "foobar barfoo" / FOO bar /ix совпадет с "foobar" "FOOBAR" "foobar and two other foos" /(foo)?bar/ совпадет с "foobar", "bar" /^foobar$/ совпадет _только_ с "foobar" /f[obar]+r/ совпадет с "foobar", "for", "far" /([\d\.])+/ задает любое число с десятичной запятой /((foo)|(bar))+/ совпадет с "foofoofoobarfoobar", "bar"