Регулярное сопоставление не-ASCII символов в sed - PullRequest
2 голосов
/ 20 апреля 2020

Рассмотрим следующую замену sed regex:

$ echo 'oóO' | sed -e 's/[^a-z]/./g'
oó.

Для меня это говорит: "замените все символы, не находящиеся в диапазоне от a до z, на ., поэтому я ожидаю вывод o.., поскольку ни neither, ни O не находятся в диапазоне a-z в смысле «кодовой точки» в любой кодировке (FWIW, я использую UTF-8).

Что с этим?

Как я могу сделать диапазон, который точно соответствует только [abcdefhijklmnopqrstuvwxyz], не выписывая все это?

Вот вывод locale в моей системе:

LANG=en_US.UTF-8
LANGUAGE=
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=

1 Ответ

2 голосов
/ 20 апреля 2020

На основании варианта предложения от Quasímodo, установка LC_COLLATE=C для команды sed работает:

$ echo 'oóO' | LC_COLLATE=C sed -e 's/[^a-z]/./g'
o..

Ключ заключается в том, чтобы изменить порядок сопоставления на " C ", так что - больше не появляется между o и p в порядке сортировки (сортировки), но не для изменения LC_CTYPE (или LC_ALL), так что многобайтовый UTF- 8 символов по-прежнему интерпретируются правильно (поэтому LC_ALL=C не работает).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...