Вход/Регистрация
Искусство программирования для Unix
вернуться

Реймонд Эрик Стивен

Шрифт:

8.2.2. Учебный пример: регулярные выражения

Одним из видов спецификации, который периодически появляется в инструментах Unix и языках сценариев, является регулярное выражение (regular expression, или regexp для краткости). Здесь регулярные выражения рассматриваются как декларативный мини-язык для описания текстовых шаблонов. Часто регулярные выражения встраиваются в другие мини-языки. Регулярные выражения настолько распространены, что их едва ли можно считать мини-языком, однако они заменяют то, что в противном случае представляло было собой огромные объемы кода, реализующего различные (и несовместимые) возможности поиска.

В данном введении не рассматриваются такие подробности, как POSIX-расширения, обратные ссылки и особенности интернационализации. Более подробное изложение способа их применения представлено в книге "Mastering Regular Expressions" [22].

Регулярные выражения описывают шаблоны, которые могут либо совпадать, либо не совпадать со строками. Простейшим средством для работы с регулярными выражениями является утилита grep(1), фильтр, который переправляет со стандартного ввода на стандартный вывод каждую строку, соответствующую указанному регулярному выражению. Форма записи регулярных выражений кратко представлена в таблице 8.1.

Таблица 8.1. Примеры регулярных выражений

Регулярное выражение Соответствующая строка
"x.y"
x, за которым следует любой символ с последующим
у
"x\.y"
х, за которым следует точка с последующим у
"xz?y"
х, за которым следует не более одного символа z с последующим у, т.е. "xy" или "xzy", но не "xz" или "xdy"
"xz*y"
х, за которым следует любое количество символов z, за которыми следует y, т.е. "xy" или "xzy" или "xzzzy", но не "xz" или "xdy"
"xz+y"
x
, за которым следует один или несколько экземпляров символа
z
, за которыми следует у, т.е. "
xzy
" или "
xzzy
", но не "
xy
", "
xz
" или "
xdy
"
"s[xyz]t"
s
, за которым следует любой из символов
х
,
у
или
z
, за которым следует
t
, т.е. "
sxt
", "
syt
" или "
szt
", но не "
st
" или "
sat
"
"a[x0-9]b"
а
, за которым следует либо
х
, либо символ в диапазоне 0-9, за которым следует
b
, то есть, "
axb
", "
a0b
" или "
а4b
", но не "
ab
" или "
aab
"
"s[^xyz] t"
s
, за которым следует любой символ, кроме
х
,
у
или
z
, за которым следует
t
, т.е. "
sdt
" или "
set
", но не "sxt", "
syt
" или "
szt
"
"s[^x0-9]t"
s
, за которым следует любой символ, кроме
x
или символа в диапазоне 0-9, за которым следует
t
, т.е. "
slt
" или "
smt
", но не "
sxt
", "
s0t
" или "
s4t
"
"^x”
x в начале строки, т.е. "
xzy
" или "
xzzy
", но не "
yzy
" или "
уху
"
"x$"
х в конце строки, т.е. "
yzx
" или "
yx
", но не "
yxz
" или "
zxy
"

Существует большое количество второстепенных вариантов записи регулярных выражений.

1. Выражения-маски. Ограниченный набор соглашений по применению символов-шаблонов (wildcard), использовавшийся в ранних оболочках Unix для сопоставления имен файлов. Существует всего 3 символа-шаблона:

*
— соответствует любой последовательности символов (как .* в других вариантах);
?
— соответствует любому единичному символу (как . в других вариантах);
[...]
— соответствует классу символов как в других вариантах. В некоторых оболочках (csh, bash, zsh) позднее был добавлен шаблон
{}
для выбора подстроки. Таким образом, выражение
x{a,b}c
соответствует строкам
xac
или
xbc
, но не
xc
. В некоторых оболочках выражения-маски получили дальнейшее развитие в направлении расширения регулярных выражений.

2. Базовые регулярные выражения. Форма записи, принятая в исходной утилите grep(1) для извлечения из файла строк, соответствующих заданному регулярному выражению. Выражения этого типа также применяются в строковом редакторе ed(1) и потоковом редакторе sed(1). Профессионалы старой школы Unix считают данное выражение основной, или "унифицированной", разновидностью регулярных выражений. Пользователи, впервые столкнувшиеся с более современными инструментами, склонны использовать расширенную форму, которая описана ниже.

3. Расширенные регулярные выражения. Запись, принятая в расширенной версии grep, egrep(1) для извлечения из файла строк, соответствующих заданному регулярному выражению. Регулярные выражения в Lex и редакторе Emacs весьма близки к egrep-разновидности.

4. Регулярные выражения языка Perl. Форма записи, принятая в regexp-функциях языков Perl и Python. Выражения этого типа являются более мощными по сравнению с egrep-вариантом.

После рассмотрения основных примеров в таблице 8.2 приведена сводка стандартных шаблонов для регулярных выражений. Следует отметить, что в таблицу не включен вариант выражений-масок, поэтому запись "для всех" означает только 3 типа: базовый, расширенный/Emacs и Perl/Python [79] .

Таблица 8.2. Введение в операции с регулярными выражениями

Символ-шаблон Поддерживается Соответствующая строка
\
во всех Начало escape-последовательности. Определяет, следует ли интерпретировать последующий знак как шаблон. Последующие буквы или цифры интерпретируются различными способами в зависимости от программы
.
во всех Любой символ
^
во всех Начало строки
$
во всех Конец строки
[...]
во всех Любой из символов, указанных в скобках
[^...]
во всех Любые символы, кроме указанных в скобках
*
во всех Любое количество экземпляров предыдущего элемента
?
egrep/Emacs, Perl/Python Ни одного или один экземпляр предыдущего элемента
+
egrep/Emacs, Perl/Python Один или несколько экземпляров предыдущего элемента
{n}
egrep, Perl/Python; как
\{n\}
в Emacs
В точности n повторений предыдущего элемента. Не поддерживается некоторыми старыми regexp-средствами
{n,}
egrep, Perl/Python; как
\{n,\}
в Emacs
n или более повторений предыдущего элемента. Не поддерживается некоторыми старыми regexp-средствами
{m,n}
egrep, Perl/Python; как
\{m,n\}
в Emacs
Минимум m и максимум n повторений предыдущего элемента. Не поддерживается некоторыми старыми regexp-средствами
| egrep, Perl/Python; как
\|
в Emacs
Элемент слева или справа. Обычно используется с некоторой формой группирующих разделителей
(...)
Perl/Python; как
\(...\)
в более старых версиях
Интерпретировать данный шаблон как группу (в более новых regexp-функциях, например в языках Perl и Python). Более старые средства, такие как regexp-функции в Emacs и в утилите grep требуют записи
\(...\)

79

Стандарт POSIX для регулярных выражений вводит некоторые символьные диапазоны, такие как

[[:lower:]]
и
[[:digit:]]
. Кроме того, отдельные специфические средства используют дополнительные символы-шаблоны, не описанные здесь. Однако для интерпретации большинства регулярных выражений приведенных примеров достаточно.

В новых языках с поддержкой регулярных выражений установилась практика Perl/Python-варианта. Он является более прозрачным, чем остальные, особенно потому, что обратная косая черта перед не алфавитно-цифровым символом всегда означает, что данный символ трактуется буквально, что значительно устраняет путаницу при ссылке на элементы регулярных выражений.

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

  • Читать дальше
  • 1
  • ...
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: