Orden de clasificación a través de LC_COLLATE
define no solo el orden de clasificación de los caracteres individuales, sino también el significado de los rangos de caracteres. ¿O sí? Considere el siguiente fragmento:
unset LANGUAGE LC_ALL
echo B | LC_COLLATE=en_US grep '[a-z]'
Intuitivamente, B
no está en [a-z]
, por lo que esto no debería generar nada. Eso es lo que sucede en Ubuntu 8.04 o 10.04. Pero en algunas máquinas que ejecutan Debian lenny o squeeze, B
se encuentra, porque el rango a-z
incluye todo lo que está entre a
y z
en el orden de clasificación, incluidas las letras mayúsculas B
a través de Z
.
Todos los sistemas probados tienen en_US
local generado. También intenté variar la configuración regional:en las máquinas donde B
coincide con la anterior, lo mismo sucede en todas las configuraciones regionales disponibles (en su mayoría basadas en latín:{en_{AU,CA,GB,IE,US},fr_FR,it_IT,es_ES,de_DE}{iso8859-1,iso8859-15,utf-8}
, también locales chinos) excepto japonés (en cualquier codificación disponible) y C
/POSIX
.
¿Qué significan los rangos de caracteres en las expresiones regulares? , cuando vas más allá de ASCII? ¿Por qué hay una diferencia entre algunas instalaciones de Debian por un lado y otras instalaciones de Debian y Ubuntu por el otro? ¿Cómo se comportan otros sistemas? ¿Quién tiene razón y contra quién debería informarse un error?
(Tenga en cuenta que estoy preguntando específicamente sobre el comportamiento de los rangos de caracteres como [a-z]
en en_US
locales, principalmente en sistemas basados en GNU libc. No estoy preguntando cómo hacer coincidir letras minúsculas o letras minúsculas ASCII).
En dos máquinas Debian, una donde B
está en [a-z]
y uno donde no lo es, la salida de LC_COLLATE=en_US locale -k LC_COLLATE
es
collate-nrules=4
collate-rulesets=""
collate-symb-hash-sizemb=1
collate-codeset="ISO-8859-1"
y la salida de LC_COLLATE=en_US.utf8 locale -k LC_COLLATE
es
collate-nrules=4
collate-rulesets=""
collate-symb-hash-sizemb=2039
collate-codeset="UTF-8"
Respuesta aceptada:
Si está utilizando algo que no sea el C
configuración regional, no debería usar rangos como [a-z]
ya que estos dependen de la configuración regional y no siempre dan los resultados esperados. Además del problema de mayúsculas y minúsculas que ya ha encontrado, algunas configuraciones regionales tratan los caracteres con signos diacríticos (p. ej., á ) igual que el carácter base (es decir, a ).
En su lugar, utilice una clase de carácter con nombre:
echo B | grep '[[:lower:]]'
Esto siempre dará el resultado correcto para la configuración regional. Sin embargo, debe elegir la configuración regional para reflejar el significado tanto del texto de entrada como de la prueba que está tratando de aplicar.
Relacionado:Php:imagechar — Dibujar un carácter horizontalmente
Por ejemplo, si necesita encontrar un valor de byte en particular, use el C
configuración regional, que siempre está disponible:
echo B | LANG=C grep '[a-z]'
Si esto no funciona como se esperaba, realmente es un error.