Компания ALT Linux
Опубликован: 14.12.2004 | Доступ: свободный | Студентов: 12603 / 1647 | Оценка: 4.19 / 3.84 | Длительность: 18:18:00
ISBN: 978-5-9556-0019-1
Лекция 14:

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

< Лекция 13 || Лекция 14: 12345 || Лекция 15 >

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

Операция выбора - |. Два РВ, разделенные '|' - составное РВ, для которого определяется подстрока, соответствующая любому из двух РВ. Например, one, TWO и = соответствуют '=|one|TWO', а =one, FooBar и Two - не соответствуют. Операция выбора - очень удобное средство, но стоит иметь в виду, что в сложных случаях, в сочетании с повторителем *, она может потребовать немало ресурсов - времени или оперативной памяти, как повезет. Подробнее об этом см. [ 27 ] .

Два частных случая повторителя-интервала: повторитель ?, обозначающий использование предшествующего атомарного РВ не более одного раза (может быть выражен с помощью '{,1}' ), и повторитель +, обозначающий использование предшествующего атомарного РВ не менее одного раза ( '{1,}' ). Оба частных случая постоянно встречаются в повседневной работе; кроме того, обработка + во многих случаях идет существенно быстрее, чем обработка *, поэтому + стоит использовать вместо * везде, где только возможно.

В расширенном РВ определяются именованные множества символов, вроде '[[:alnum:]]' (ему соответствует одна буква или одна цифра), или '[[:blank:]]' (ему соответствует один разделитель - пробел или табуляция). Все именованные множества описаны в руководстве. Главное достоинство именованных множеств - привязка к национальному языку (если она реализована в утилите, использующей РВ): буквой считается не только латинская, но и - в нашем случае - русская буква. Если то же РВ использовать в немецких настройках, задействованные в этом языке латинские буквы с диакритическими знаками или двойное s тоже будут соответствовать '[[:alpha:]]' или '[[:alnum:]]'. По этой же причине рекомендуется не использовать именованные множества, если установленный язык заранее неизвестен.

Таблица 14.1. Пример расширенного регулярного выражения
Регулярное выражение Соответствует Не соответствует
'a.c' abc, aWc, a+c ac, a..c, cba
'F.*d' FddFd, Freud, F.*d feed, Sigmund, dF
'u..[p-t]' user, u##s, uppp undo, uncut, u=t
'wuff(-wuff)*' wuff, wuff-wuff-wuff wuffwuff, wuff-
'[+-]?[0-9]+' +1, -0932, 333 +-7, -, 0+0
'[fit|plug](in|out)+' fitin, pluginoutin infit, plug, outin

К $ и ^ добавлено еще два позиционных оператора, '[[:<:]]' и '[[:>:]]', которым соответствует начало и конец слова (здесь уместно процитировать параграф BUGS руководства re_format: "The syntax for word boundaries is incredibly ugly"). Строго говоря, эти позиционные операторы слегка расширяют класс распознаваемых подстрок, потому что результат поиска '[[:>:]]' зависит от символа, который не входит в подстроку-результат, т. е. зависит от контекста.

Новый синтаксис РВ получил название расширенного (extended) регулярного выражения.

Толкование неоднозначностей

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

Избавиться от неоднозначности при поиске подстроки в строке помогает правило левый-длинный (leftmost longest, дословный перевод: самая левая - самая длинная). Если в строке встречается несколько подстрок, которые соответствуют РВ, из них будет выбрана в качестве ответа та, что раньше всех начинается, то есть самая левая. Если при этом с одного и того же места в строке начинается несколько подстрок, соответствующих РВ, то среди них будет выбрана самая длинная. Например, из всех возможных соответствий выражению 'a.*d' в строке The syntax for word boundaries is incredibly ugly будет соответствовать подстрока от самого левого a до самого правого d: ax for word boundaries is incred.

Выражению 'B*' в строке BBcBBBd можно найти 17 соответствий (из них одна подстрока BBB, 3 BB, 5 B и 8 пустых подстрок в различных позициях). Правильным ответом будет BB в начале строки, потому что, во-первых, это самая левая из возможных подстрок, а во-вторых, самая длинная (среди допустимых, B и BB ). А вот в строке aBBcBBBd первой будет найдена пустая подстрока, потому что 'B*' имеет cоответствие в самом начале строки, и притом ровно одно: пустую подстроку.

Если некоторая подстрока может быть поставлена в соответствие составному РВ несколькими способами, правило левый-длинный применяется так: среди всех возможных ответов выбираются ответы с наибольшей длиной самого левого фрагмента (соответствующего самому левому атомарному РВ ). Среди оставшихся выбираются ответы с наибольшей длиной второго фрагмента и т. д. до конца регулярного выражения. Например, при поиске '[0-9]+[0-9]+' в строке a123c5678d будет найдена подстрока 123, причем 12 будет соответствовать первому '[0-9]+', а 3 - второму.

Почему так? Во-первых, 5678 отпадает, потому что есть соответствие, которое лежит ближе к началу строки, - 123. Во-вторых, будет найдено именно 123, а не 1 или 12, потому что 123 - самое длинное из возможных соответствий. В-третьих, начальное '[0-9]+' и радо бы захватить для себя всю 123, но тогда на долю второго не остается ничего, и соответствия всему РВ не получается. Так что оно вынуждено уступить второму '[0-9]+' хотя бы один символ - 3.

Подобное поведение регулярных выражений привело к тому, что во вполне серьезной литературе их называют жадными (greedy). "Жадность" регулярных выражений - удобное свойство, на него всегда можно положиться (в смысле однозначности ответа), однако встречаются задачи, решать которые было бы удобнее, если бы выбиралось самое короткое, а не самое длинное соответствие. Многие инструментарии, использующие регулярные выражения, включают в себя диалекты "нежадных" (non-greedy) РВ, например, вводят "нежадные" повторители. Важно знать, что с помощью "нежадных" РВ можно задать язык, не принадлежащий классу регулярных; это, с одной стороны, заметно расширяет наши возможности (непонятно только, часто ли они бывают востребованы), но, с другой стороны, отменяет все предположения о времени поиска и однозначности результата, сделанные для классического варианта РВ.

< Лекция 13 || Лекция 14: 12345 || Лекция 15 >
Max Akt
Max Akt

Я прохожу курс "Операционная система Unix" и после тестов, вижу в отчете, что этот тест сдало еще 25 человек. Почему так мало, это ведь реально хороший и полезный урок. Здесь естьи теория и практичесские материалы. Сам курс написан хорошо, живым языком. И здесь я получил ответы на вопросы по Linux, которые боялся спросить. Наверное это из-за того, что в названии курса написано не Linux, а Unix и это многих отпугивает.

Andranik Avakian
Andranik Avakian

41. УК РФ и Комментарии (ст. 273)

М. 2000 г. Издательство: ALT Linux, Институт Логики

Уголовный Кодекс РФ и комментарии к нему?

По ссылке открывается сайт документации Linux, раздел Linux Installation and Getting Started