Was bedeutet [[.ch.]] In einer Regex?

11

Alternativer Titel: Was ist eine "Sortiersequenz" oder ein "Sortierelement" in einem POSIX-kompatiblen regulären Ausdruck?

Ich habe die genaue technische Definition in Abschnitt 9.3.5 der POSIX-Spezifikationen als Punkt 4 in der Liste gefunden, aber es ist mir nicht wirklich klar.

Ich habe im Internet nach Beispielen und Erklärungen gegoogelt und bin nicht mit leeren Händen aufgetaucht , aber definitiv nicht aufgeklärt .

Das einzige, was ich irgendwie bekommen habe, ist, dass Sie Ihre Regex unter bestimmten Umständen dazu bringen können, mehrere Zeichen so zu behandeln, als wären sie ein einzelnes Zeichen, um die Länge zu vergleichen und die "längste Übereinstimmung" zu bestimmen (da Regexe gierig sind und Rückgabe der längstmöglichen Übereinstimmung).

Ist das alles? Ich habe Probleme, eine Verwendung dafür zu finden, aber ich vermute, dass mein Verständnis unvollständig ist. Was ist eigentlich "Zusammenstellen" für einen regulären Ausdruck? Und wie hängt [[.ch.]]das Beispiel in den POSIX-Spezifikationen damit zusammen?

Platzhalter
quelle

Antworten:

7

Sortierelemente werden normalerweise im Zusammenhang mit der Sortierung referenziert.

In vielen Sprachen erfolgt die Sortierung (Sortieren wie in einem Wörterbuch) nicht nur pro Zeichen. Zum Beispiel wird auf Tschechisch chnicht zwischen cgund ciwie auf Englisch sortiert, sondern als Ganzes zum Sortieren betrachtet. Es ist ein Sortierelement (wir können uns hier nicht auf ein Zeichen beziehen, Zeichen sind eine Teilmenge von Sortierelementen), das zwischen hund sortiert i.

Nun fragen Sie sich vielleicht: Was hat das mit regulären Ausdrücken zu tun? , Warum sollte ich in einem Klammerausdruck auf ein Sortierelement verweisen wollen? .

Nun, innerhalb von Klammerausdrücken verwendet man die Reihenfolge. Zum Beispiel in [c-j]möchten Sie die Zeichen zwischen cund j. Na ja, oder? Sie möchten dort lieber Elemente zusammenstellen. [h-i]in einem tschechischen Gebietsschema entspricht ch:

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

Wenn Sie also in der Lage sind, eine Reihe von Sortierelementen in einem Klammerausdruck aufzulisten, können Sie davon ausgehen, dass Sie sie auch einzeln auflisten können. [a-cch]würde das Sortieren von Elementen zwischen aund cund den cund hZeichen übereinstimmen . Um a-cund das chSortierelement zu haben , benötigen wir eine neue Syntax:

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

(die dazwischen aund cund die cheine).

Jetzt ist die Welt noch nicht perfekt und wird es wahrscheinlich nie. Das obige Beispiel war auf einem GNU-System und funktionierte. Ein anderes Beispiel eines Zusammentragelement sein könnte , emit einer Kombination von Akut in UTF-8 ( $'e\u0301'gerendert wie $'\u00e9'als é).

é und é sind dasselbe Zeichen, außer dass eines mit einem Zeichen und das andere mit zwei Zeichen dargestellt wird.

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

Funktioniert auf einigen Systemen ordnungsgemäß, auf anderen jedoch nicht (z. B. nicht auf GNU-Systemen). Und es ist unklar, ob $'[[.\ue9.]]'nur $'\ue9'oder beides übereinstimmen soll $'\ue9'und $'e\u301'.

Ganz zu schweigen von nicht-alphabetischen Skripten oder Skripten mit unterschiedlichen regionalen Sortierreihenfolgen, z. B. ffi ( ffiin einem Zeichen), die mit einer so einfachen API schwierig zu handhaben sind.

Stéphane Chazelas
quelle
1

Dies ist nützlich, wenn nicht englische (nicht ASCII) Zeichen verwendet werden. Das Beispiel, das chSie erwähnen, ist ein Digraph , dh einige Sprachen haben einen Buchstaben in ihrem Alphabet, der durch zwei Buchstaben in einem englischen Alphabet dargestellt werden kann / kann.

Wenn Sie [.ch.]einen regulären Ausdruck verwenden, sagen Sie im Grunde: "Ich erwarte eine nicht englische Eingabesequenz mit dem Digraphen ch. Ich möchte, dass mein regulärer Ausdruck mit dem einzelnen Zeichen übereinstimmt ch. Meine Programmiersprache / Regex-Engine / Tastatur erlaubt mir nicht, diese Digraphen zu schreiben." Zeichen, also tippe ich ein [.ch.]. Ich meine nicht ein cgefolgt von einem h. Bitte finden Sie nur Vorkommen des Digraphen als einen einzelnen Zeichen. "

[[.ch.]]bedeutet, dass der Digraph Teil eines Zeichensatzes ist. In diesem Fall eigentlich nur ein Zeichen. Nur Standard-Regexp-Notation.

Rolf
quelle
Von Stephane Antwort sieht es aus wie ch ist eigentlich zwei verschiedene Charaktere; Es wird nur zum Sortieren als eins behandelt. Sind Sie sicher, dass "Digraph" ein zutreffender Begriff ist?
Wildcard