Книжная полка Сохранить
Размер шрифта:
А
А
А
|  Шрифт:
Arial
Times
|  Интервал:
Стандартный
Средний
Большой
|  Цвет сайта:
Ц
Ц
Ц
Ц
Ц

Регулярные выражения Perl и их применение

Покупка
Новинка
Артикул: 825020.01.99
Доступ онлайн
1 000 ₽
В корзину
Подробное неформальное описание синтаксиса и механизма работы регулярных выражений языка Perl с примерами использования от простых к сложным. Описание с нуля синтаксиса и механизма работы регулярных выражений Perl, алгоритма работы оператора m//, s///, split, всех конструкций, используемых в регулярных выражениях. Сложные случаи применения регулярных выражений (динамические регулярные выражения, использование встроенного кода). Объекты регулярных выражений. Хронометраж и ускорение работы регулярных выражений. Побочные действия регулярных выражений (установка переменных $1, …, @-, @+, $’ и т.д.). Учебные и практические примеры использования регулярных выражений. Юникод не рассматривается.
Мельников, С. В. Регулярные выражения Perl и их применение : краткий учебный курс / С. В. Мельников. - Москва : ИНТУИТ, 2016. - 163 с. - ISBN 978-5-94774-797-3. - Текст : электронный. - URL: https://znanium.ru/catalog/product/2137128 (дата обращения: 03.03.2024). – Режим доступа: по подписке.
Фрагмент текстового слоя документа размещен для индексирующих роботов. Для полноценной работы с документом, пожалуйста, перейдите в ридер.
Регулярные выражения Perl и их применение

2-е издание, исправленное

Мельников С.В.

Национальный Открытый Университет “ИНТУИТ”
2016

2
УДК 004.652.4(075.8)
ББК 17
Т83
PERL для профессиональных программистов. Регулярные выражения / Мельников С.В. - M.:
Национальный Открытый Университет “ИНТУИТ”, 2016 (Основы информационных технологий)
ISBN 978-5-94774-797-3

Подробное неформальное описание синтаксиса и механизма работы регулярных выражений языка
Perl с примерами использования от простых к сложным.
Описание с нуля синтаксиса и механизма работы регулярных выражений Perl, алгоритма работы
оператора m//, s///, split, всех конструкций, используемых в регулярных выражениях. Сложные случаи
применения регулярных выражений (динамические регулярные выражения, использование
встроенного кода). Объекты регулярных выражений. Хронометраж и ускорение работы регулярных
выражений. Побочные действия регулярных выражений (установка переменных $1, …, @-, @+, $’ и
т.д.). Учебные и практические примеры использования регулярных выражений. Юникод не
рассматривается.

(c) ООО “ИНТУИТ.РУ”, 2007-2016
(c) Мельников С.В., 2007-2016

3
Создание регулярных выражений

Начальное знакомство с регулярными выражениями: одиночные символы, классы
символов, альтернативные шаблоны, квантификаторы (числители), их “жадность” и ее
ограничение, мнимые символы (якоря), захватывающие скобки и ссылки на найденный
текст.

1.1. Общее знакомство с регулярными выражениями

Если на компьютере у читателя еще не установлена система программирования Perl, то
самое время это сделать. Дистрибутив Perl под Windows можно скачать с сайта ссылка:
http://www.activestate.com - http://www.activestate.com. Это все дается бесплатно.
Поставка осуществляется в дистрибутиве MSI (MicroSoft Installer). Вы можете
запустить его, найдя этот файл через “Мой компьютер” и дважды щелкнув на нем.
Также можно использовать инсталлятор msiexec.exe, находящийся в подкаталоге
system32 каталога Windows. Если запустить его без параметров, он в окне выдаст
справку на русском языке.

Регулярные выражения обычно используются как операнды операторов поиска m/…/ и
замены s/…/…/. Слово регулярные означает “составленные по правилам”. То, что стоит
вместо многоточия в операторе m и вместо первого многоточия в операторе s, - это и
есть регулярное выражение. Буква m означает match (соответствие), а буква s означает
substitution (замена) .

Предположим, в программе проверяется ввод пользователя, чтобы выяснить, хочет ли
он завершить программу, введя слова stop, quit, exit или abort. Без регулярных
выражений вам пришлось бы использовать ряд сравнений с этими образцами,
предварительно преобразовав ввод к нижнему регистру. С оператором m эта проверка
делается просто:

if ($input =~ m/stop|quit|exit|abort/i) { exit }

Вы можете также проверить, что пользователь кроме ключевого слова больше ничего
не вводил. Для этого оператор m надо записать так:

if ($input =~ m/^(stop|quit|exit|abort)$/i) { exit }

Мы предполагаем, что ввод пользователя содержится в переменной $input. Символы ”

=~ ” надо рассматривать как единый символ, это оператор связывания переменной

$input с данным оператором m. Этот оператор связывания возвратит число 1, если
оператор поиска m найдет в $input текст, соотнесенный с шаблоном, иначе вернется
пустая строка, которая в Perl трактуется как ложь. Поэтому оператор поиска удобно
использовать в условных операторах и заголовках операторов цикла.

Символы ” / ” не принадлежат к регулярному выражению, а лишь ограничивают его
подобно скобкам. Транслятор по ним определяет, где начинается и заканчивается
регулярное выражение, которое может быть очень большим и сложным. Если символ-

4
ограничитель используется в любом месте регулярного выражения, то он должен быть
замаскирован обратным слэшем: \/. Это может порождать частокол из обратных и
прямых слэшей внутри регулярного выражения, что часто встречается у новичков.
Синтаксис Perl позволяет выбирать в качестве ограничителей почти любые символы,
кроме алфавитно-цифровых и пробельных: #, !, ,, :, % и т.д. Например, оператор

print ':' =~ m:[abc\:def]:;

напечатает единицу. Символы-ограничители лучше выбирать по возможности такими,
которые не встречаются в регулярном выражении, чтобы не усложнять его вид. Также
лучше не использовать символы ” *, +, -, |, (, ), [, ], {, } “, потому что в
регулярном выражении они играют особую роль.

Символы-ограничители могут быть парными: это все виды скобок (), <>, [] и {}.
Имеются в виду символы ASCII, т.к. существуют угловые скобки, не принадлежащие к
7-битным символам. В этом случае перед регулярным выражением ставится
открывающая скобка, а после него - закрывающая.

Если в качестве ограничителей выступают слэши ” / “, то букву m можно не писать.
Здесь еще следует добавить, что если ограничителями выступают вопросительные
знаки, то букву m также можно не ставить, но эти ограничители включают довольно
экзотический режим поиска, которые относится к “подозрительным” экспериментам и
может не войти в будущие версии Perl.

Если в качестве целевого текста для оператора поиска или замены выступает
переменная $_, то ее можно опустить вместе со связкой

=~: if (/stop|quit|exit|abort/i) { exit }

Буква i после завершителя регулярного выражения называется модификатором и
включает режим поиска без учета регистра букв (case Insensitive). При этом шаблон

/StOp/i будет соответствовать целевой строке ‘stop’, ‘sTOp’ и т.д.

Понятие буквы зависит от локальных установок среды выполнения программы. В
русской Windows к буквам также будут относиться все русские буквы в кодировке
Windows. Во французской Windows результаты будут другими. Существуют
специальные директивы и операторы установки локали ( use locale и setlocale ), но
аргумент setlocale может отличаться для разных операционных систем. Как
установить локаль в Perl на сервере, надо уточнять у его администратора.

1.1.1 Альтернативные шаблоны

Символ ” | “, напоминающий операцию ” или “, играет в регулярных выражениях роль,
схожую с этой логической связкой. Это конструкция выбора ( альтернативы ). Дойдя
до нее, система поиска соответствия начинает с текущей позиции целевой строки
сопоставлять ей все шаблоны из конструкции выбора ( альтернативные шаблоны ) в
порядке их написания (т.е. слева направо). Используется первый совпавший шаблон,

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

Оператор ” | ” имеет очень низкий приоритет, поэтому, если перед или после
конструкции выбора имеется еще что-то, то ее надо заключить в скобки.

Во втором примере символ ” ^ ” означает начало строки, а символ ” $ ” - ее конец.
Точный смысл этих символов мы обсудим позже. Эти символы также называют
мнимыми символами, т.к. они совпадают не с текстом, а с позицией в целевой строке.
Также их еще называют условиями, якорными метасимволами или просто якорями.

Если бы во втором примере регулярное выражение было записано без скобок:

^stop|quit|exit|abort$

то оно бы означало следующее: либо stop в начале строки, либо слова quit или exit в
любом месте строки, либо abort, стоящее в конце строки. А это было бы не то, что нам
нужно.

1.1.2 Модификаторы и якоря

А теперь рассмотрим другие модификаторы регулярных выражений. Модификатор m
(Multiline) меняет смысл якорей ^ и $: в зоне его действия метасимвол ^ соответствует
не только началу текста, но также началу каждой логической строки в этом тексте, т.е
совпадает в начале текста и после каждого символа новой строки \n, который не стоит
в самом конце текста. Метасимвол $ в зоне действия модификатора m совпадает не
только в самом конце текста, но также и перед каждым символом \n. Но тогда
необходимо иметь еще пару якорей, которые совпадают лишь в начале и конце текста.
И такие якоря есть, их даже три.

Условие \A совпадает только в самом начале текста.
Условие \Z совпадает только в самом конце текста и перед символом \n, который
стоит в самом конце текста. (Например, на случай, если к этому тексту не
применили функцию chomp ).
Условие \z совпадает исключительно в самом конце текста. Модификаторы на
эти три якоря не действуют.

Еще имеется мнимый символ \b, который соответствует границе слова (word Boundary).
Он соответствует позиции, с одной стороны которой находится буква, цифра или знак
подчерка, а с другой стороны такого символа нет. Мнимый символ \B имеет
противоположный смысл: он соответствует позиции внутри слова, т.е. с одной и
другой стороны к нему примыкает буква, цифра или знак подчерка. Заметим, что эти
якоря чувствительны к локальной установке (локали).

6
В регулярном выражении точка ” .” является метасимволом и соответствует одному
любому символу за исключением символа новой строки \n. Но в зоне действия
модификатора s точка соответствует одному любому символу. Такое различие бывает
нужно, чтобы операция поиска не вышла за пределы логической строки.

В последней версии регулярных выражений появился метасимвол \C, который
соответствует ровно одному байту независимо от того, является ли этот байт началом
многобайтового символа или нет. Т.к. мы многобайтовые символы не рассматриваем,
то можно в начале программы написать директиву

use bytes;

которая заставит Perl рассматривать символы как однобайтовые. Это, а также замена
метасимвола точка на \C, даст некоторое ускорение работы регулярных выражений.

1.1.3 Классы символов

Как быть, если в данной позиции целевой строки могут стоять (ожидаются) разные
символы? Например, параметры тега HTML могут заключаться в апострофы, а также
двойные кавычки. Здесь конструкцию выбора применять неудобно. Для этого
существуют классы символов. Класс - это последовательность символов, которая
заключена в квадратные скобки. Например, класс [””] совпадает с апострофом и с
двойной кавычкой.

Заметьте, что класс символов всегда соответствует ровно одному символу целевой
строки. Кроме того, нельзя создавать пустые классы символов, т.е. такие классы,
которые не соответствуют ни одному символу. Транслятор не всегда может это
проверить, и ошибка будет на совести программиста.

Классы имеют свои метасимволы, а некоторые метасимволы регулярных выражений
внутри классов не действуют. Например, символ ] является метасимволом лишь
внутри класса и поэтому должен быть в нем замаскирован: \]. А символ [ является
метасимволом в регулярном выражении, но не внутри класса символов.

Внутри класса символов можно использовать диапазоны символов, например, класс [a-

f0-9] - это то же, что [abcdef0123456789], но первая запись короче. Диапазон
включает все промежуточные символы, чьи коды расположены между кодами крайних
символов. Если вы захотите включить знак минус в класс символов, то его надо либо
замаскировать обратным слэшем, либо поставить в самом начале или конце класса.

Символ ” ^ ” внутри класса уже не означает начала строки, мнимые символы внутри
классов не имеют смысла и не используются. Символ ” ^ “, который стоит в самом
начале класса, инвертирует этот класс, и такой инвертированный класс соответствует
любому из символов, кроме перечисленных в этом классе.

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

7
\d соответствует десятичной цифре: [0-9].

\D соответствует одному символу, не являющемуся цифрой: [^0-9].

\w соответствует символу, входящему в слово: [a-zA-Z0-9_]. Но вы должны
помнить, что этот класс чувствителен к локальной установке и может включать
символы букв национального алфавита.

\W соответствует любому символу, не входящему в слово: [^a-zA-Z0-9_]. Он тоже
чувствителен к локали.

\s соответствует одному “пробельному” символу. Пробельными символами
считаются:

пробел с десятичным кодом 32 ;
горизонтальная табуляция \t с кодом 9 ;
перевод строки \n с кодом 10 ;
возврат каретки \r с кодом 13 ;
перевод формата \f с кодом 12.

Таким образом, \s - это класс [ \t\r\n\f].

\S соответствет непробельному символу: [^ \t\r\n\f].

Еще заметим, что если класс символов находится в зоне действия модификатора i, то в
этот класс неявно включаются соответствующие буквы также другого регистра, чтобы
он соответствовал символу без учета регистра букв. Например, класс [a-c] в зоне
действия модификатора i соответствует символу из диапазонов a-cA-C, а класс [^a] в
зоне действия модификатора i уже не соответствует символу A.

Для задания символа по его коду можно воспользоваться эскейп-последовательностью
вида \xHH, где HH - две шестнадцатеричные цифры кода символа. Например, \x20 - это
символ пробела, а \xFF - код буквы “я” в кодировке Windows (это число 255).
Шестнадцатеричные цифры можно набирать в любом регистре, а буква x должна быть
в нижнем регистре.

Имеется возможность использовать для этого также восьмеричную систему, например,

\040 - код пробела и \377 - код буквы “я”. После обратной косой должно быть ровно
три восьмеричных цифры. Но я не советую пользоваться восьмеричной системой, т.к.
это вступает в конфликт с обозначением обратных ссылок, о которых речь еще
впереди.

1.1.4 Квантификаторы, их “жадность” и ее ограничение

Ознакомимся с квантификаторами, также именуемыми числителями или
повторителями. Если после подшаблона стоит квантификатор, то этот шаблон может
повторяться столько раз, сколько указывает этот квантификатор. Например, шаблон

a{0,4} соответствует нулю, одной, двум, трем и четырем буквам ” a “, идущим подряд.

Соответствие нулю каких-то символов означает соответствие пустой подстроке. Если
максимальный параметр не ограничен, то его можно опустить: шаблон a{1,}

8
соответствует последовательности из одной и более букв ” а “. Шаблон a{3}
соответствует ровно трем подряд буквам a, это то же, что и шаблон aaa.

В Perl есть ограничение на максимальное значение квантификатора: 32766. Это
связано с тем, что применение квантификаторов требует запоминания состояний,
чтобы в последующем в случае неудачи поиска вернуться и попробовать варианты с
другим числом повторений. Этот вопрос мы рассмотрим позднее.

Некоторые числители используются так часто, что для них сделали краткие формы
записи:

a* - это нуль или больше символов a: a{0,} ;

a+ - это один или больше символов a: a{1,} ;

a? - это нуль или один символ a: a{0,1}.

Квантификаторы имеют высокий приоритет, поэтому шаблон bil+ing соответствует
символам bi, после которых идет одна или больше букв l и далее последовательность

ing. Если вы хотите, чтобы квантификатор соответствовал последовательности
символов или группе подшаблонов, то эту конструкцию надо взять в скобки:

(bil)+ing
соответстсвует строкам
biling
bilbiling
bilbilbiling
и т.д.

По умолчанию, алгоритм работы квантификаторов таков, что они пытаются захватить
как можно больше текста, который им соответствует. Например, в переменной $text
имеем текст

<b>Текст выделен жирным шрифтом.</b> Простой текст <b>Это опять жирный</b>

Если применить к этому тексту регулярное выражение <b>.+</b>: $text =~ /<b>.+

</b>/ то оно будет соответствовать всему этому тексту, а не фрагменту <b>Текст
выделен жирным шрифтом.</b>

Аналогично, в шаблоне

\w*a

примененном к строке

abcabcaaaaa

подшаблон \w* будет соответствовать подстроке

abcabcaaaa

9
(без последней буквы a ), а не подстроке

abca

или

abcabca

Имеется способ заставить квантификаторы захватывать как можно меньше текста, для
этого после такого квантификатора надо поставить знак вопроса: ” ?”. Например:

a+?

соответствует минимуму из одной и более букв ” a “. Если этот шаблон применить к
строке

bbbaaaabbb

то такой минимальный квантификатор захватит первую попавшуюся букву а, после
чего оператор поиска закончит работу, вернув число 1.

В шаблоне

a*?

минимальный квантификатор удовлетворится нулем символов a, а это значит, что
совпадение будет найдено в любом месте, даже после истинного конца строки!
Оператор

print "a" =~ /\za*/;

напечатает 1.

Вот другие примеры минимальных квантификаторов:

\w?
(abc){3,5}?

1.1.5 Захватывающие и незахватывающие скобки

Поиск соответствия давал бы мало пользы, если бы нельзя было извлекать из текста
интересующие нас фрагменты. Для извлечения фрагмента текста часть шаблона (или
весь шаблон ), который ему соответствует, надо заключить в круглые скобки. Всего в
регулярном выражении может быть 99 захватывающих пар скобок. Такие скобки также
называют сохраняющими. Если вы не хотите сохранять часть текста, а только
группируете подшаблоны, то для этого существуют обычные скобки, которые не
сохраняют текст; таких скобок в регулярном выражении может быть 200 пар. Чтобы
сделать пару скобок обычной ( несохраняющей ), надо сразу после открывающей

10
Доступ онлайн
1 000 ₽
В корзину