[me@linuxbox ~]$ echo $LANG
en_US.UTF-8
При проверке этой настройки POSIX-совместимые приложения используют лексикографический порядок, а не порядок следования символов в наборе ASCII. Это объясняет поведение команд, рассмотренное выше. Когда диапазон символов [A-Z] интерпретируется в лексикографическом порядке, он включает все алфавитные символы, кроме символа a в нижнем регистре, — именно это объясняет полученный результат.
Для частичного решения этой проблемы стандарт POSIX предусматривает несколько классов символов, описывающих диапазоны символов. Они перечислены в табл. 19.2.
Таблица 19.2. Название таблицы
Класс символов
|
Описание
|
[:alnum:]
|
Алфавитно-цифровые символы; эквивалент диапазона [A-Za-z0-9] в ASCII
|
[:word:]
|
То же, что и [:alnum:], с дополнительным символом подчеркивания (_)
|
[:alpha:]
|
Алфавитные символы; эквивалент диапазона [A-Za-z] в ASCII
|
[:blank:]
|
Включает символы пробела и табуляции
|
[:cntrl:]
|
Управляющие символы ASCII; включает символы ASCII с кодами от 0 до 31 и 127
|
[:digit:]
|
Цифры от 0 до 9
|
[:graph:]
|
Отображаемые символы; включает символы ASCII с кодами от 33 до 126
|
[:lower:]
|
Символы нижнего регистра
|
[:punct:]
|
Знаки пунктуации; эквивалент класса [-!"#$%&'()*+,./:;<=>?@[\\\]_`{|}~] в ASCII
|
[:print:]
|
Печатаемые символы; все символы из класса [:graph:] и пробел
|
[:space:]
|
Пробельные символы, включая пробел, табуляцию, возврат каретки, перевод строки, вертикальную табуляцию и перевод формата; эквивалент класса [ \t\r\n\v\f] в ASCII
|
[:upper:]
|
Символы верхнего регистра
|
[:xdigit:]
|
Символы, используемые для представления шестнадцатеричных цифр; эквивалент класса [0-9A-Fa-f] в ASCII
|
возврат к традиционному порядку сортировки
Есть возможность вернуть систему к традиционному (ASCII) порядку сортировки, изменив значение переменной окружения LANG. Как было показано в предыдущем разделе, переменная LANG хранит название языка и набора символов, заданных в региональных настройках. Значение этой переменной первоначально определяется в момент, когда выбирается язык установки дистрибутива Linux.
Увидеть региональные настройки можно, выполнив команду locale:
[me@linuxbox ~]$ locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
Чтобы установить региональные настройки, обеспечивающие традиционное поведение системы Unix, присвойте переменной LANG значение POSIX:
[me@linuxbox ~]$ export LANG=POSIX
Имейте в виду, что в результате наших действий система будет использовать набор символов американского английского (точнее, ASCII), поэтому подумайте, действительно ли это то, что вам нужно.
Эти изменения можно сделать постоянными, добавив следующую строку в файл .bashrc:
export LANG=POSIX
Но даже наличие классов символов не дает удобного способа выражения частичных диапазонов, таких как [A-M].
Используя классы символов, можно повторить пример с выводом содержимого каталога и посмотреть, насколько улучшился результат.
[me@linuxbox ~]$ ls /usr/sbin/[[:upper:]]*
/usr/sbin/MAKEFLOPPIES
/usr/sbin/NetworkManagerDispatcher
/usr/sbin/NetworkManager
Но не забывайте, что это не является примером использования регулярных выражений, скорее это пример того, как командная оболочка выполняет подстановку путей. Мы рассмотрели его лишь потому, что классы символов POSIX поддерживаются и там и там.
Простые и расширенные регулярные выражения POSIX
Как раз когда, казалось бы, проблема путаницы с диалектами регулярных выражений решена, обнаруживается, что стандарт POSIX также делит реализации регулярных выражений на два вида: простые регулярные выражения (Basic Regular Expressions, BRE) и расширенные регулярные выражения (Extended Regular Expressions, ERE). Особенности, рассматривавшиеся до сих пор, поддерживаются всеми POSIX-совместимыми приложениями и приложениями, реализующими BRE. Программа grep — одна из них.
Чем отличаются BRE и ERE? Различия касаются наборов метасимволов. В диалекте BRE распознаются следующие метасимволы: ^ $ . [ ] *. Все остальные считаются литералами. В ERE во множество метасимволов (с соответствующими им функциями) добавляются: ( ) { } ? + |.
Однако (что самое интересное) символы ( ) { } интерпретируются в BRE как метасимволы, если они экранированы символом обратного слеша, тогда как в ERE присутствие обратного слеша перед этими же метасимволами превращает их в литералы.
Читать дальше