Simplemente una adición a las respuestas ya excelentes, si es contradictorio.
La documentación para la biblioteca PCRE siempre ha declarado que "Los rangos operan en la secuencia de clasificación de los valores de los caracteres". Lo cual es algo vago, pero muy preciso.
Se refiere al cotejo por el índice de caracteres en las tablas de caracteres internos de PCRE, que se puede configurar para que coincida con la localización actual usando pcre_maketables
. Esa función crea las tablas en orden de valor de char (tolower(i)
/toupper(i)
)
En otras palabras, no se clasifica por orden de clasificación cultural real (la información de intercalación de locale). Como ejemplo, mientras que el alemán trata ö lo mismo que o en la recopilación del diccionario, ö tiene un valor que lo hace aparecer fuera del rango az en todas las codificaciones de caracteres comunes usadas para el alemán (ISO-8859-x, codificaciones unicode, etc.) En este caso, PCRE basaría su determinación de si ö está en el rango [a-z]
en ese valor de código, en lugar de cualquier orden de clasificación definido en la configuración regional real.
PHP ha copiado en generalal es literal en their docs. Sin embargo, se han tomado la molestia de cambiar la declaración anterior a "Los rangos operan en secuencia de clasificación ASCII". Esa declaración ha estado en los documentos al menos desde 2004.
A pesar de lo anterior, no estoy muy seguro de que sea cierto, sin embargo.
Bueno, no en todos los casos, al menos.
El PHP hace una llamada a pcre_maketables
... Desde el PHP source:
#if HAVE_SETLOCALE
if (strcmp(locale, "C"))
tables = pcre_maketables();
#endif
En otras palabras, si el entorno para el que se compila PHP tiene setlocale
y la (LC_CTYPE) local no está se usa la configuración regional POSIX/C, el orden de caracteres de la configuración regional POSIX/C del entorno de ejecución. De lo contrario, se utilizan las tablas de PCRE por defecto - que son generados (por pcre_maketables
) al compilar PCRE - basado en la configuración regional del compilador:
Esta función construye un conjunto de tablas de caracteres para los valores de carácter menos de 256. Estos pueden pasarse a pcre_compile() para anular las tablas integradas internas de PCRE (que fueron hechas por pcre_maketables() cuando se compiló PCRE).Es posible que desee hacer esto si está utilizando una configuración regional no estándar. La función produce un puntero a las tablas.
Mientras alemana no sería diferente para [a-z]
en cualquier codificación de caracteres común, si se tratase de EBCDIC, por ejemplo, [a-z]
incluiría ± e ~. De acuerdo, EBCDIC es la codificación de un carácter que puedo pensar que no coloca a-z y A-Z en una secuencia ininterrumpida.
A menos que PCRE haga algo de magia cuando use EBCDIC (y podría serlo), mientras que es muy poco probable que incluya diéresis en cualquier cosa que no sea la construcción PHP más oscura o el entorno de tiempo de ejecución (usando su propia, muy especial, personalizada definición de entorno local hecho), podría, en el caso de EBCDIC, incluir otros caracteres no deseados. Y para otros rangos, "intercalado en secuencia ASCII" no parece del todo exacto.
ETA: que podría haber salvado algunas investigaciones mediante la búsqueda de la respuesta del propio Philip Hazel a una preocupación similar:
Otro problema es con las clases de caracteres varía. Podrías pensar que [a-k] y [x-z] están bien definidos para los scripts latinos, pero ese no es el caso.
Son, ciertamente, bien definido, que es equivalente a [\ x61- \ X6B] y [\ x78- \ X7a], es decir, relacionados con el orden del código, no orden de clasificación cultural.
¿Fue esto realmente cierto en 2009? –
@WalterTross Sigue siendo tan cierto hoy como lo era en aquel entonces. Nunca se trata de lo que era/es común, se trata de lo que PODRÍA suceder con alguna configuración extraña, y de asegurarse de que su código sea lo suficientemente robusto como para manejarlo. –
@ AlanStorm, ¿puede proporcionar una configuración tan extraña? ¡Estoy bastante seguro de que no hay ninguno! –