Que signifie [[.ch.]] Dans une expression régulière?

11

Titre alternatif: Qu'est-ce qu'une "séquence de classement" ou un "élément de classement" dans une expression régulière compatible POSIX?

J'ai trouvé la définition technique exacte dans la section 9.3.5 des spécifications POSIX , comme élément n ° 4 dans la liste, mais ce n'est pas vraiment clair pour moi.

Je suis allé sur Google pour trouver des exemples et des explications et je suis venu pas complètement les mains vides, mais certainement pas éclairé .

La seule chose que j'ai en quelque sorte obtenue, c'est que dans certaines circonstances, vous pouvez faire en sorte que votre regex traite plusieurs caractères comme s'il s'agissait d'un seul caractère à des fins de comparaison de longueur et de détermination de la «correspondance la plus longue» (puisque les regex sont gourmandes et retourner la correspondance la plus longue possible).

C'est tout, cependant? J'ai du mal à en voir l'usage, mais je soupçonne que ma compréhension est incomplète. Qu'est-ce que "collationner" pour une expression régulière? Et comment cela se [[.ch.]]rapporte-t-il à l'exemple des spécifications POSIX?

Caractère générique
la source

Réponses:

7

Les éléments de classement sont généralement référencés dans le contexte du tri.

Dans de nombreuses langues, le classement (tri comme dans un dictionnaire) ne se fait pas uniquement par caractère. Par exemple, en tchèque, chne trie pas entre cget cicomme il le ferait en anglais, mais est considéré comme un tout pour le tri. C'est un élément de classement (nous ne pouvons pas faire référence à un caractère ici, le caractère est un sous-ensemble d'éléments de classement) qui trie entre het i.

Vous pouvez maintenant vous demander: qu'est - ce que cela a à voir avec les expressions régulières? , Pourquoi voudrais-je faire référence à un élément d'assemblage dans une expression entre crochets? .

Eh bien, à l'intérieur des expressions entre crochets, on utilise l'ordre. Par exemple dans [c-j], vous voulez les caractères entre cet j. Eh bien, vous? Vous préférez y rassembler des éléments. [h-i]dans une locale tchèque correspond ch:

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

Donc, si vous êtes en mesure de répertorier une plage d'éléments d'assemblage dans une expression entre crochets, vous vous attendez à pouvoir également les répertorier individuellement. [a-cch]correspondrait à ces éléments de classement entre aet cet les caractères cet h. Pour avoir a-cet l' chélément d'assemblage, nous avons besoin d'une nouvelle syntaxe:

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

(ceux entre aet cet chcelui).

Maintenant, le monde n'est pas encore parfait et ne le sera probablement jamais. L'exemple ci-dessus était sur un système GNU et fonctionnait. Un autre exemple d'un élément d' assemblage peut être eune combinaison accent aigu en UTF-8 ( $'e\u0301'rendu comme $'\u00e9'aussi é).

é et é sont le même caractère sauf que l'un est représenté avec un caractère et l'autre avec deux.

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

Fonctionnera correctement sur certains systèmes mais pas sur d'autres (pas GNU par exemple). Et on ne sait pas si $'[[.\ue9.]]'doit correspondre uniquement $'\ue9'ou les deux $'\ue9'et $'e\u301'.

Sans parler des scripts non alphabétiques, ou des scripts avec des ordres de tri différents et régionaux, des choses comme ffi ( ffien un seul caractère) qui deviennent difficiles à gérer avec une API aussi simple.

Stéphane Chazelas
la source
1

Ceci est utile lorsque des caractères non anglais (non ascii) sont utilisés. L'exemple que chvous mentionnez est un digraphe , c'est-à-dire que certaines langues ont une lettre dans leur alphabet qui est / peut être représentée par deux lettres dans un alphabet anglais.

Lorsque vous utilisez [.ch.]dans une expression rationnelle, vous dites essentiellement: "Je m'attends à une séquence d'entrée non anglaise avec le digraphe ch. Je veux que mon expression rationnelle corresponde au caractère unique ch. Mon langage de programmation / moteur / clavier regex ne me permet pas d'écrire ce digraphe signe, donc je tape [.ch.]. Je ne veux pas dire un csuivi d'un h. Veuillez trouver uniquement les occurrences du digraphe comme un seul caractère. "

[[.ch.]]signifie que le digraphe fait partie d'un ensemble de caractères. Dans ce cas, un seul caractère en fait. Juste notation regexp standard.

Rolf
la source
D'après la réponse de Stéphane, il semble que ce ch soit en fait deux personnages différents; il est simplement traité comme un à des fins de tri. Êtes-vous sûr que "digraph" est un terme applicable?
Wildcard