Порядок сортировки через LC_COLLATEопределяет не только порядок сортировки отдельных символов, но и значение диапазонов символов. Или это? Рассмотрим следующий фрагмент:
unset LANGUAGE LC_ALL
echo B | LC_COLLATE=en_US grep '[a-z]'
Интуитивно, Bне в [a-z], так что это не должно ничего выводить. Вот что происходит в Ubuntu 8.04 или 10.04. Но на некоторых машинах, на которых запущен Debian lenny или squeeze, Bвстречается, потому что диапазон a-zвключает в себя все, что находится между aи zв порядке сортировки, включая заглавные буквы до Bконца Z.
Все протестированные системы имеют en_USсгенерированную локаль. Я также пытался варьировать локаль: на машинах, где Bуказано выше, то же самое происходит в каждой доступной локали (в основном на латинице:, {en_{AU,CA,GB,IE,US},fr_FR,it_IT,es_ES,de_DE}{iso8859-1,iso8859-15,utf-8}также китайские локали), кроме японской (в любой доступной кодировке) и C/ POSIX.
Что означают диапазоны символов в регулярных выражениях , когда вы выходите за рамки ASCII? Почему существует разница между некоторыми установками Debian с одной стороны и другими установками Debian и Ubuntu с другой? Как ведут себя другие системы? Кто прав, и кому следует сообщать об ошибке?
(Обратите внимание, что я специально спрашиваю о поведении диапазонов символов, например [a-z]в en_USлокалях, в первую очередь в системах на основе GNU libc. Я не спрашиваю, как сопоставлять строчные или строчные буквы ASCII.)
На двух машинах Debian, один из которых Bнаходится в [a-z]и один , где он не, выход LC_COLLATE=en_US locale -k LC_COLLATEIS
collate-nrules=4
collate-rulesets=""
collate-symb-hash-sizemb=1
collate-codeset="ISO-8859-1"
а выходной сигнал LC_COLLATE=en_US.utf8 locale -k LC_COLLATEIS
collate-nrules=4
collate-rulesets=""
collate-symb-hash-sizemb=2039
collate-codeset="UTF-8"
Cязыковой стандарт используется в качестве запасного варианта, и его порядок сопоставления - прямые байтовые значения, поэтому Bне будет совпадать. Тест в локали, которая появляется в выходных данных locale -a.
en_USгенерируется, хотя.