# regexp

Сравнивает строку и регулярное выражение.

## СИНТАКСИС

          regexp ?switches? exp string ?matchVar? ?subMatchVar subMatchVar...?

## ОПИСАНИЕ

Команда определяет, соответствует ли регулярное выражениеexp какой-либо части строки string или всей строке, и возвращает 1, если соответствует, и 0 - в противном случае.

Если в команде указаны дополнительные аргументы после string, они считаются именами переменных, в которые возвращается информация о том, какие именно части строки соответствуют регулярным выражениям. Переменной присваивается значение, состоящее из части строки, соответствующей всему регулярному выражению. Самой левой в списке переменной subMatchVar присваивается значение, состоящее из части строки, которая соответствует самому левому заключенному в скобки выражению в составе exp. Следующей переменной subMatchVar присваивается значение, соответствующее следующему заключенному в скобки выражению, и так далее.

Если первые аргументы команды начинаются с -, они считаются опциями команды. Ниже перечислены возможные опции.

-nocase
  При сравнении не различает буквы в верхнем и нижнем регистре.
-indices
  В переменных subMatchVars сохраняются не части строки, а списки из двух десятичных чисел - индексов начала и конца соответствующей области строки.
--
  Означает конец опций. следующий аргумент будет рассматриваться как exp, даже если он начинается с -.

Если в команде указано больше переменных subMatchVar, чем выражений в скобках в exp, или если для одного из выражений не удалось найти соответствующую ему часть строки, то соответствующей переменной будет присвоено значение -1 или пустая строка, в зависимости от того, была ли задана опция -indices.

## РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ

Регулярное выражение состоит из ни одной или более ветвей (branch), разделенных символом '|'. Строка соответствует выражению, если она соответствует одной из его ветвей.

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

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

Атом может быть регулярным выражением в скобках (в этом случае он соответствует любой строке, которая соответствует этому регулярному выражению), интервалом (см. ниже), символом '.' (соответствует ровно одному произвольному символу), '^' (соответствует нулевой строке в начале string), '$' (соответствует нулевой строке в конце string), '\' с последующим одним символом (соответствует этому символу), или одним символом без какого-либо иного смысла (соответствует этому символу).

Интервал есть последовательность символов, заключенная в квадратные скобки. Он обычно соответствует любому символу из этого интервала. Если последовательность начинается с символа '^', то она соответствует любому символу, кроме символов, стоящих далее в последовательности. Если два символа в последовательности разделены символом '-', то это краткая форма для обозначения всех ASCII символов между этими двумя (например, '[0-9]' соответствует любой десятичной цифре). Для того, чтобы включить в последовательность символ ']', следует поставить его на место первого в последовательности (следом за возможным символом '^'). Для включения в последовательность символа '-' следует сделать его первым или последним символом.

## ВЫБОР ИЗ АЛЬТЕРНАТИВНЫХ СОСТОЯНИЙ

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

          regexp (a*)b* aabaaabb x y

В соответствии с описанными выше правилами переменные x и y могут принять значение aabb и aa, aaab и aaa, ab и a или одну из еще нескольких возможных комбинаций. Чтобы избежать этой потенциальной неопределенности команда regexp выбирает между возможными вариантами по правилу "первый и самый длинный". Другими словами, строка и регулярное выражение просматриваются слева направо, при этом выбирается часть строки максимально возможной длины. Говоря точнее, при выборе используются следующие правила в порядке убывания приоритета.

[1] | Если регулярное выражение соответствует двум разным частям строки, выбирается та часть, которая раньше начинается. Если обе начинаются в одном и том же месте, то это неопределенный (тяжелый) случай. Его можно объяснить следующим образом.
[2] | Если регулярное выражение содержит символы | (то есть состоит из нескольких ветвей), то будет выбрана самая левая ветвь, которой что-либо соответствует.
[3] | Для выражений, содержащих '*', '+' и '?', выбираются самые длинные фрагменты строки, соответствующие им.
[4] | Компоненты выражений рассматриваются слева направо.

В приведенном выше примере (a*)b* соответствует aab, так как для (a*) выбирается первый соответствующий ему фрагмент, то есть начальные aa, а затем для b* выбирается следующий символ b. Рассмотрим еще один пример:

          regexp (ab|a)(b*)c abc x y z

После выполнения команды переменная x будет содержать значение abc, переменная y - ab и переменная z будет содержать пустую строку. Правило [4] определяет, что поиск начнется с выражения (ab|a), а правило [2], что поиск начнется с подвыражения ab. Поэтому символ b в строке будет использован, и выражение (b*) будет соответствовать пустой строке.