` | PARSER | документация |

parser

faqfaq
авторыавторы
документациядокументация

в действиив действии
куда говоритькуда говорить
жаргонжаргон

скачатьскачать

примерыпримеры
форумфорум

документация

Приложение C.
Регулярные выражения в стандарте POSIX 1003.2

Внимание! Нижеследующий текст является переводом man-страницы, размещенной по адресу http://www.gsp.com/cgi-bin/man.cgi?section=7&topic=re_format.

Описание

Регулярные выражения (РВ), описанные в стандарте POSIX 1003.2, имеют два различных синтаксиса: современные РВ (примерно такие как egrep, называемые в стандарте 1003.2 “расширенными” РВ) и устаревшие РВ (примерно такие как ed, называемые в стандарте 1003.2 “базовыми” РВ). Устаревшие РВ существуют главным образом для обеспечения обратной совместимости в некоторых старых программах. Эти выражения будут описаны в самом конце данного документа. Стандарт 1003.2 оставляет открытыми многие аспекты синтаксиса и семантики РВ, вследствие чего некоторые решения, построенные на данном стандарте, могут быть не полностью совместимы с другими реализациями на его же основе. Значок “§” отмечает такие потенциально частично несовместимые решения.

Современные РВ представляют собой одну или несколько непустых секций (branches), разделенных знаком “|”. Соответствие определяется по любой секции такого выражения.

Секция состоит из одной или нескольких соединенных частей (pieces). Соответствие определяется сначала для первой части, потом для второй и т. д.

Часть представляет собой элементарное выражение (atom), вслед за которым может следовать один из символов “*”, “+”, “?” или же ограничитель (bound). Элементарное выражение и “*” допускают 0 или более соответствий. Элементарное выражение и “+” допускают одно или более соответствий, а элементарное выражение и “?” допускают 0 или 1 соответствие.

Ограничитель представляет собой конструкцию, начинающуюся с открывающей скобки “{”, за которой следует беззнаковое десятичное целое число, возможно с последующей запятой “,” и еще одним беззнаковым десятичным целым числом. Вся эта конструкция обязательно закрывается правой скобкой “}”. Значения целых чисел могут лежать в интервале от 0 до RE_DUP_MAX (255) включительно, и в случае использования двух значений первое не должно превышать второе.

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

Элементарное выражение может быть заключенным в круглые скобки “()” регулярным выражением (соответствие определяется по регулярному выражению), пустыми круглыми скобками (соответствует пустой строке), ограниченным выражением — bracket expression (см. далее), точкой “.” (соответствует одному любому символу), знаком “^” (соответствует пустой подстроке в начале строки), знаком “$” (соответствует пустой подстроке в конце строки); сочетанием “\” и одного из следующих символов “^.[$()|*+?{\” (соответствует одному обычному символу), сочетанием “\” и любого другого символа (соответствует одному обычному символу, как при отсутствии “\”), а также единственным неслужебным символом (соответствует этому символу).

Символ “{” вместе с последующим обычным символом, не являющимся цифрой, не считается началом ограничителя, а символ “\” не может служить концом РВ.

Ограниченное выражение представляет собой перечень заключенных в квадратные “[]” скобки символов. При этом соответствие обычно определяется по какому-либо одному из символов в списке (исключение см. далее). Если перечень символов начинается со знака “^”, соответствие определяется по любому символу с начала списка (исключение см. далее). Если два символа в списке разделены знаком “-”, — это означает непрерывное подмножество полного диапазона символов, расположенное между двумя указанными символами включительно, т. е. “[0-9]” в ASCII-кодировке соответствует любой десятичной цифре. При использовании двойного диапазона конечная граница оказывается неопределенной, например в случае “a-c-e”. Применение диапазонов символов сильно зависит от последовательности сравнения и поэтому настоятельно не рекомендуется при разработке переносимых программ.

При включении в список знака “]” в качестве сравниваемого символа он должен быть первым (следуя возможно за “^”). В этом же случае знак “-” должен быть первым или последним символом или же второй границей диапазона. Для использования при сравнении знака “-” в качестве первой границы диапазона его необходимо заключить в квадратные скобки “[” и “]” (см. далее). За исключением вышеописанных случаев и некоторых комбинаций с использованием “[” (см. следующий параграф), любые другие специальные символы, включая “\”, утрачивают свое служебное значение внутри ограниченного выражения.

Внутри ограниченного выражения элемент сопоставления (символ; последовательность нескольких символов, рассматриваемая как единственный символ; или имя сравниваемой последовательности для одного из предыдущих случаев), заключенный в квадратные скобки “[” и “]”, образует сравниваемую последовательность из этих символов. Эта последовательность представляет из себя единственный элемент в списке ограниченного выражения. Таким образом, ограниченное выражение, содержащее сравниваемую последовательность из нескольких символов, может соответствовать более чем одному символу: например, если сравниваемая последовательность включает элемент “ch”, то РВ “[[.ch.]]*c” будет соответствовать первым пяти символам в последовательности “chchcc”.

Внутри ограниченного выражения заключенный в “[=” и “=]” элемент сопоставления рассматривается как класс эквивалентности, образующий последовательности сравниваемых символов, которые точно соответствуют этому элементу, включая его самого. (При отсутствии другого эквивалентного элемента сопоставления обработка последовательности символов аналогична случаю закрывающих скобок “[” и “]”.) Например, если “o” и “^” входят в класс эквивалентности, то тогда сочетания “[[=o=]]”, “[[=^=]]” и “[o^]” являются синонимами. Класс эквивалентности может служить границей диапазона.

Внутри ограниченного выражения имя класса символов, заключенное в “[:” и “:]”, образует перечень всех символов, принадлежащих данному классу. Существуют следующие стандартные классы символов:

alnum alpha blank cntrl
digit graph lower print
punct space upper xdigit

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

Существуют два особых вида ограниченных выражений: ограниченные выражения “[[:<:]]” и “[[:>:]]” соответствуют нулевой строке в начале и конце слова. Слово, определяется как ограниченная последовательность символов. Используемые в слове символы относятся к классу alnum (определяется через ctype), а также могут являться символом подчеркивания. Этот синтаксис не описан в стандарте POSIX 1003.2, однако является совместимым с ним и может аккуратно использоваться при создании переносимого программного обеспечения.

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

Длина соответствия определяется по числу символов, а не по сравниваемым элементам. Нулевая строка считается длиннее строки, которая вообще не имеет соответствий. Например, “bb*” соответствует трем символам в середине “abbbc”, а “(wee|week)(knights|nights)” соответствует десяти символам в “weeknights”. При сравнении “(.*).*” с “abc” заключенное в скобки подвыражение соответствует всем трем символам, а при сравнении “(a*)*” с “bc” все регулярное выражение, а также его заключенная в скобки часть соответствуют нулевой строке.

Независимое от регистра сравнение не учитывает различия при использовании больших и малых букв. Если тот или иной независимый от регистра символ появляется за пределами ограниченного выражения, он легко преобразуется в ограниченное выражение, содержащее оба его регистра, т. е. “x” превращается “[xX]”. Аналогично, при появлении такого символа внутри ограниченного выражения происходит сопряжение регистров, т. е. “[x]” становится “[xX]”, а “[[invalid operator x]” — “]”.

На длину РВ не накладывается никаких ограничений, поэтому для сохранения POSIX-совместимости в переносимых программах нельзя использовать РВ длиннее 256 байт.

Устаревшие (“базовые”) регулярные выражения имеют несколько отличий. В “базовых” РВ “|” рассматривается как обычный символ и не имеет никакого функционального эквивалента. “+” и “?” также являются обычными символами, а их функциональность задается с помощью соответствующих ограничителей {1,} и {0,1}. Обратите внимание на то, что “x+” в современных регулярных выражениях эквивалентно “xx*”. В “базовых” РВ ограничителями являются “\{” и “\}”, в то время как “{” и “}” сами по себе рассматриваются как обычные символы. Скобки для вложенных подвыражений задаются с помощью “\(” и “\)”, а простые скобки “(” и “)” являются обычными символами. Знак “^” считается обычным символом, за исключением случая, когда он находится в начале РВ, а также в начале заключенного в скобки подвыражения. Знак “$” считается обычным символом, за исключением случая, когда он находится в конце РВ, а также в конце заключенного в скобки подвыражения. Знак “*” считается обычным символом, за исключением случая, когда он находится в начале РВ, а также в начале заключенного в скобки подвыражения (возможно после символа “^”). Наконец, в современных РВ существует новый тип элементарного выражения — back reference, которое представляет из себя последовательность из знака “\” и ненулевого десятичного числа. Данное выражение соответствует d-му, заключенному в скобки подвыражению (нумерация подвыражений задается по порядку их следования справа налево), т. е., например “\([bc]\)\1” соответствует “bb” или “cc”, но не “bc”.

Ошибки

Существует два вида приводящих к ошибкам РВ.

В существующей спецификации “)” рассматривается как обычный символ при отсутствии закрывающей “)”. Это приводит к неожиданным ошибкам разбиения на слова. Средство очевидно — избегайте этого.

Использование выражений типа back reference может иметь катастрофические ошибки даже в эффективных решениях, поскольку такие выражения бывают неоднозначными (разве “a\(\(b\)*\2\)*d” соответствует “abbbd”?). Избегайте этого.

Спецификация 1003.2 на независимое от регистра соответствие также расплывчата. У разработчиков в данный момент принято такое определение: “Один регистр подразумевает оба регистра”.

Синтаксис ограничителей слов просто ужасен

.


E-mail: mailbox@parser.ruCopyright © 1997-2001 Студия Артемия Лебедева
`