¿Qué significa [[.ch.]] En una expresión regular?

11

Título alternativo: ¿Qué es una "secuencia de clasificación" o un "elemento de clasificación" en una expresión regular compatible con POSIX?

Encontré la definición técnica exacta en la Sección 9.3.5 de las especificaciones POSIX , como el ítem # 4 en la lista, pero no me queda claro.

Googled alrededor en la web para ver ejemplos y explicaciones y se le ocurrió no por completo con las manos vacías, pero definitivamente no es iluminado .

Lo único que he conseguido es que, en determinadas circunstancias, puede hacer que su expresión regular trate a varios caracteres como si fueran un solo carácter para fines de comparación de longitud y determinar cuál es la "coincidencia más larga" (ya que las expresiones regulares son codiciosas y devolver el partido más largo posible).

¿Eso es todo? Tengo problemas para ver su uso, pero sospecho que mi comprensión es incompleta. ¿Qué es realmente "cotejar" para una expresión regular? ¿Y cómo [[.ch.]], el ejemplo en las especificaciones POSIX, se relaciona con esto?

Comodín
fuente

Respuestas:

7

Los elementos de intercalación generalmente se mencionan en el contexto de la ordenación.

En muchos idiomas, la clasificación (clasificación como en un diccionario) no solo se realiza por carácter. Por ejemplo, en checo, chno clasifica entre cgy cicomo lo haría en inglés, pero se considera como un todo para la clasificación. Es un elemento de clasificación (no podemos referirnos a un carácter aquí, los caracteres son un subconjunto de elementos de clasificación) que se clasifica entre hy i.

Ahora puede preguntar: ¿Qué tiene eso que ver con las expresiones regulares? , ¿Por qué querría referirme a un elemento de clasificación en una expresión de paréntesis? .

Bueno, dentro de las expresiones entre corchetes, uno usa el orden. Por ejemplo [c-j], en , desea los caracteres entre cy j. Bueno Prefieres clasificar elementos allí. [h-i]en partidos locales checos ch:

$ echo cho | LC_ALL=cs_CZ.UTF-8 grep '^[h-i]o'
cho

Entonces, si puede enumerar un rango de elementos de clasificación en una expresión de paréntesis, entonces esperaría poder enumerarlos individualmente también. [a-cch]coincidiría con los elementos de clasificación entre ay cy los caracteres cy h. Para tener a-cy el chelemento de clasificación, necesitamos una nueva sintaxis:

$ echo cho | LC_ALL=cs_CZ.UTF-8 grep '^[a-c[.ch.]]o'
cho

(los de entre ay cy el chuno).

Ahora, el mundo aún no es perfecto y probablemente nunca lo será. El ejemplo anterior estaba en un sistema GNU y funcionó. Otro ejemplo de un elemento de clasificación podría ser econ un acento agudo combinado en UTF-8 ( $'e\u0301'representado $'\u00e9'como é).

é y é son el mismo carácter, excepto que uno está representado con un carácter y el otro con dos.

$ echo $'e\u301t\ue9' | grep '^[d-f]t'

Funcionará correctamente en algunos sistemas pero no en otros (no en GNU, por ejemplo). Y no está claro si $'[[.\ue9.]]'debería coincidir solo $'\ue9'o ambos $'\ue9'y $'e\u301'.

Sin mencionar las secuencias de comandos no alfabéticas, o las secuencias de comandos con diferentes órdenes de clasificación regionales, cosas como ffi ( ffien un carácter) que se vuelven difíciles de manejar con una API tan simple.

Stéphane Chazelas
fuente
1

Esto es útil cuando se usan caracteres que no están en inglés (no ascii). El ejemplo chque menciona es un dígrafo , es decir, algunos idiomas tienen una letra en su alfabeto que está / puede ser representada por dos letras en un alfabeto inglés.

Cuando lo usa [.ch.]en una expresión regular , básicamente dice: "Espero una secuencia de entrada que no esté en inglés con el dígrafo ch. Quiero que mi chexpresión regular coincida con el carácter único . Mi lenguaje de programación / motor de expresiones regulares / teclado no me permite escribir este digrafo signo, así que escribo. [.ch.]No me refiero a cseguido de un h. Por favor, solo encuentre las ocurrencias del dígrafo como un carácter único ".

[[.ch.]]significa que el dígrafo es parte de un conjunto de caracteres. En este caso, solo un personaje en realidad. Solo notación regexp estándar.

Rolf
fuente
A partir de la respuesta de Stéphane parece que ch es en realidad dos caracteres diferentes; solo se trata como uno para fines de clasificación. ¿Estás seguro de que "digraph" es un término aplicable?
Comodín el