Книга: Искусство программирования для Unix
8.2.2. Учебный пример: регулярные выражения
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 требуют записи (...) |
В новых языках с поддержкой регулярных выражений установилась практика Perl/Python-варианта. Он является более прозрачным, чем остальные, особенно потому, что обратная косая черта перед не алфавитно-цифровым символом всегда означает, что данный символ трактуется буквально, что значительно устраняет путаницу при ссылке на элементы регулярных выражений.
Регулярные выражения являются исключительным примером того, насколько лаконичным может быть мини-язык. Простые регулярные выражения отражают режим распознавания, который иначе пришлось бы реализовывать с помощью сотен строк туманного, чреватого ошибками кода.
- 8.2.1. Учебный пример: sng
- 8.2.2. Учебный пример: регулярные выражения
- 8.2.3. Учебный пример: Glade
- 8.2.4. Учебный пример: m4
- 8.2.5. Учебный пример: XSLT
- 8.2.6. Учебный пример: инструментарий Documenter's Workbench
- 8.2.7. Учебный пример: синтаксис конфигурационного файла fetchmail
- 8.2.8. Учебный пример: awk
- 8.2.9. Учебный пример: PostScript
- 8.2.10. Учебный пример: утилиты bc и dc
- 8.2.11. Учебный пример: Emacs Lisp
- 8.2.12 Учебный пример: JavaScript
- 3.14. Примеры регулярных выражений
- Пример установочного скрипта
- Пример из практики
- ПРИМЕР ПРОСТОЙ ПРОГРАММЫ НА ЯЗЫКЕ СИ
- Индексы по выражениям
- Выражения в значениях по умолчанию для доменов
- Выражения в EXCEPTION
- Примеры получения статистики
- Пример применения метода «пять почему»
- Пример 12-8. Частота встречаемости отдельных слов
- 1.2.5. Пример программы
- Пример 17-10. Блочный комментарий