Вот список символов, которые являются специальными в регулярном выражении.
— это специальный символ, который соответствует любому одиночному символу, кроме перевода строки. Используя конкатенацию, мы можем создавать регулярные выражения, такие как ‘a.b’, которое соответствует любой трёхсимвольной строке, начинающейся с ‘a’ и заканчивающейся на ‘b’.
— сам по себе не является конструкцией; это постфиксный оператор, означающий повторение предыдущего регулярного выражения столько раз, сколько возможно. Таким образом, ‘o*’ соответствует любому количеству символов ‘o’ (включая их отсутствие).
‘*’ всегда применяется к наименьшему возможному предыдущему выражению. Так, ‘fo*’ содержит повторение ‘o’, а не повторение ‘fo’. Оно соответствует ‘f’, ‘fo’, ‘foo’ и так далее.
Механизм сопоставления обрабатывает конструкцию ‘*’, находя как можно больше повторений немедленно. Затем он продолжает работу с остальной частью шаблона. Если это не удаётся, происходит возврат (backtracking), при котором некоторые из совпадений конструкции, изменённой ‘*’, отбрасываются в надежде, что это позволит сопоставить остальную часть шаблона. Например, при сопоставлении ‘ca*ar’ со строкой ‘caaar’, ‘a*’ сначала пытается сопоставить все три ‘a’; но остаток шаблона — это ‘ar’, и для сопоставления остаётся только ‘r’, поэтому эта попытка проваливается. Следующая альтернатива — чтобы ‘a*’ сопоставила только два ‘a’. При таком выборе остальная часть регулярного выражения сопоставляется успешно.
— это постфиксный оператор, аналогичный ‘*’, за исключением того, что он должен сопоставлять предыдущее выражение как минимум один раз. Так, например, ‘ca+r’ соответствует строкам ‘car’ и ‘caaaar’, но не строке ‘cr’, тогда как ‘ca*r’ соответствует всем трём строкам.
— это постфиксный оператор, аналогичный ‘*’, за исключением того, что он должен сопоставлять предыдущее выражение либо один раз, либо ни разу. Например, ‘ca?r’ соответствует ‘car’ или ‘cr’; ничему другому.
— это нежадные варианты операторов ‘*’, ‘+’ и ‘?’. Тогда как эти операторы сопоставляют наибольшую возможную подстроку (согласующуюся с сопоставлением всего содержащего выражения), нежадные варианты сопоставляют наименьшую возможную подстроку (согласующуюся с сопоставлением всего содержащего выражения).
Например, регулярное выражение ‘c[ad]*a’ при применении к строке ‘cdaaada’ сопоставляет всю строку; а регулярное выражение ‘c[ad]*?a’, применённое к той же строке, сопоставляет только ‘cda’. (Наименьшее возможное сопоставление для ‘[ad]*?’, которое позволяет сопоставить всё выражение целиком — это ‘d’.)
— это скобочное выражение (также известное как альтернатива символов), которое начинается с ‘[’ и завершается ‘]’. В простейшем случае символы между двумя скобками — это то, чему может соответствовать данное скобочное выражение.
Таким образом, ‘[ad]’ соответствует либо одному ‘a’, либо одному ‘d’, а ‘[ad]*’ соответствует любой строке, состоящей только из ‘a’ и ‘d’ (включая пустую строку). Отсюда следует, что ‘c[ad]*r’ соответствует ‘cr’, ‘car’, ‘cdr’, ‘caddaar’ и т.д.
Вы также можете включать диапазоны символов в скобочное выражение, записывая начальный и конечный символы с ‘-’ между ними. Таким образом, ‘[a-z]’ соответствует любой строчной букве ASCII. Диапазоны могут свободно смешиваться с отдельными символами, как в ‘[a-z$%.]’, что соответствует любой строчной букве ASCII или символам ‘$’, ‘%’ или точке. Однако конечный символ одного диапазона не должен быть началом другого; например, ‘[a-m-z]’ следует избегать.
Скобочное выражение также может задавать именованные классы символов (см. Классы символов). Например, ‘[[:ascii:]]’ соответствует любому символу ASCII. Использование класса символов эквивалентно перечислению каждого символа из этого класса; но последнее на практике невозможно, поскольку некоторые классы включают тысячи различных символов. Класс символов не должен фигурировать как нижняя или верхняя граница диапазона.
Обычные специальные символы регулярных выражений не являются специальными внутри скобочного выражения. Здесь специальным является совершенно другой набор символов: ‘]’, ‘-’ и ‘^’. Чтобы включить ‘]’ в скобочное выражение, поместите его в начало. Чтобы включить ‘^’, поместите его куда угодно, но не в начало. Чтобы включить ‘-’, поместите его в конец. Таким образом, ‘[]^-]’ соответствует всем трём этим специальным символам. Вы не можете использовать ‘\’ для экранирования этих трёх символов, поскольку ‘\’ здесь не является специальным.
Следующие аспекты диапазонов специфичны для Emacs, в том смысле, что POSIX допускает, но не требует такого поведения, и программы, отличные от Emacs, могут вести себя иначе:
case-fold-search не равен nil, ‘[a-z]’ также соответствует заглавным буквам.
Некоторые виды скобочных выражений не являются наилучшим стилем, даже если они имеют чётко определённое значение в Emacs. К ним относятся:
‘[^’ начинает дополнительное скобочное выражение (или дополнительную альтернативу символов). Оно соответствует любому символу, кроме указанных. Таким образом, ‘[^a-z0-9A-Z]’ соответствует всем символам кроме букв и цифр ASCII.
‘^’ не является специальным в скобочном выражении, если только он не стоит первым символом. Символ, следующий за ‘^’, обрабатывается так, как если бы он был первым (иными словами, ‘-’ и ‘]’ там не являются специальными).
Дополнительное скобочное выражение может соответствовать переводу строки, если перевод строки не указан как один из символов, которым не следует соответствовать. Это отличается от обработки регулярных выражений в таких программах, как grep.
Вы можете задавать именованные классы символов, как и в скобочных выражениях. Например, ‘[^[:ascii:]]’ соответствует любому не-ASCII символу. См. Классы символов.
При сопоставлении в буфере ‘^’ соответствует пустой строке, но только в начале строки в сопоставляемом тексте (или в начале доступной части буфера). В противном случае он ничему не соответствует. Таким образом, ‘^foo’ соответствует ‘foo’, которое встречается в начале строки.
При сопоставлении со строкой, а не с буфером, ‘^’ соответствует началу строки или позиции после символа перевода строки.
По исторической совместимости ‘^’ является специальным только в начале регулярного выражения или после ‘\(’, ‘\(?:’ или ‘\|’. Хотя в других контекстах ‘^’ является обычным символом, хорошей практикой является использование ‘\^’ даже в этих случаях.
аналогичен ‘^’, но соответствует только в конце строки (или в конце доступной части буфера). Таким образом, ‘x+$’ соответствует строке из одного или более ‘x’ в конце строки.
При сопоставлении со строкой, а не с буфером, ‘$’ соответствует концу строки или позиции перед символом перевода строки.
По исторической совместимости ‘$’ является специальным только в конце регулярного выражения или перед ‘\)’ или ‘\|’. Хотя в других контекстах ‘$’ является обычным символом, хорошей практикой является использование ‘\$’ даже в этих случаях.
выполняет две функции: экранирует специальные символы (включая ‘\’) и вводит дополнительные специальные конструкции.
Поскольку ‘\’ экранирует специальные символы, ‘\$’ — это регулярное выражение, которое соответствует только ‘$’, а ‘\[’ — только ‘[’, и так далее.
Обратите внимание, что ‘\’ также имеет специальное значение в синтаксисе чтения строк Lisp (см. Тип строки) и должен экранироваться с помощью ‘\’. Например, регулярное выражение, соответствующее символу ‘\’, — это ‘\\’. Чтобы записать строку Lisp, содержащую символы ‘\\’, синтаксис Lisp требует экранировать каждый ‘\’ другим ‘\’. Следовательно, синтаксис чтения для регулярного выражения, соответствующего ‘\’, — это "\\\\".
По исторической совместимости оператор повторения обрабатывается как обычный, если он встречается в начале регулярного выражения или после ‘^’, ‘\`’, ‘\(’, ‘\(?:’ или ‘\|’. Например, ‘*foo’ обрабатывается как ‘\*foo’, а ‘two\|^\{2\}’ обрабатывается как ‘two\|^{2}’. Полагаться на такое поведение — плохая практика; используйте правильное экранирование обратной косой чертой в любом случае, независимо от того, где находится оператор повторения.
Поскольку ‘\’ не является специальным внутри скобочного выражения, он никогда не может снять специальное значение с ‘-’, ‘^’ или ‘]’. Вам не следует экранировать эти символы, когда они не имеют специального значения. Это ничего не прояснит, поскольку обратные косые черты могут законно предшествовать этим символам там, где они имеют специальное значение, как в ‘[^\]’ ("[^\\]" для синтаксиса строк Lisp), что соответствует любому одиночному символу, кроме обратной косой черты.
На практике большинство ‘]’, встречающихся в регулярных выражениях, закрывают скобочное выражение и, следовательно, являются специальными. Однако иногда регулярное выражение может пытаться сопоставить сложный шаблон из литеральных ‘[’ и ‘]’. В таких ситуациях иногда может потребоваться тщательно разобрать regexp с самого начала, чтобы определить, какие квадратные скобки заключают скобочное выражение. Например, ‘[^][]]’ состоит из дополнительного скобочного выражения ‘[^][]’ (которое соответствует любому одиночному символу, не являющемуся квадратной скобкой), за которым следует литеральный ‘]’.
Точные правила таковы: в начале regexp ‘[’ является специальным, а ‘]’ — нет. Это продолжается до первого неэкранированного ‘[’, после чего мы находимся внутри скобочного выражения; ‘[’ больше не является специальным (за исключением случаев, когда он начинает класс символов), но ‘]’ является специальным, если только он непосредственно не следует за специальным ‘[’ или за этим ‘[’, за которым следует ‘^’. Это продолжается до следующего специального ‘]’, который не завершает класс символов. Это завершает скобочное выражение и восстанавливает обычный синтаксис регулярных выражений; неэкранированный ‘[’ снова становится специальным, а ‘]’ — нет.