Co oznacza [[.ch.]] W wyrażeniu regularnym?

11

Alternatywny tytuł: Co to jest „kolejność zestawiania” lub „element zestawiania” w wyrażeniu regularnym zgodnym z POSIX?

Dokładną definicję techniczną znalazłem w rozdziale 9.3.5 specyfikacji POSIX , jako pozycja nr 4 na liście, ale nie jest to dla mnie jasne.

Przeszukiwałem Internet, szukając przykładów i wyjaśnień, i wymyśliłem, że nie jestem całkowicie pusty, ale zdecydowanie nie jestem oświecony .

Jedyną rzeczą, jaką dostałem, jest to, że w pewnych okolicznościach możesz sprawić, by regex traktował wiele znaków tak, jakby były pojedynczymi znakami dla celów porównania długości i określenia, co to jest „najdłuższe dopasowanie” (ponieważ wyrażenia regularne są zachłanne i zwraca najdłuższy możliwy wynik).

Czy to wszystko? Mam problem z widzeniem zastosowania, ale podejrzewam, że moje zrozumienie jest niepełne. Czym właściwie jest „zestawianie” wyrażenia regularnego? Jak [[.ch.]]odnosi się do tego przykład ze specyfikacji POSIX?

Dzika karta
źródło

Odpowiedzi:

7

Elementy sortowania są zwykle przywoływane w kontekście sortowania.

W wielu językach sortowanie (sortowanie jak w słowniku) odbywa się nie tylko według znaków. Na przykład w języku czeskim chnie sortuje się między nimi cgi citak jak w języku angielskim, ale uważa się za całość do sortowania. Jest to element zestawiający (nie możemy tutaj odnosić się do znaku, znak jest podzbiorem elementów zestawiających), który sortuje pomiędzy hi i.

Teraz możesz zapytać: co to ma wspólnego z wyrażeniami regularnymi? , Dlaczego miałbym chcieć odwoływać się do elementu zestawiającego w wyrażeniu nawiasowym? .

Cóż, w wyrażeniach w nawiasach używa się kolejności. Na przykład w [c-j]chcesz, aby znaki były pomiędzy ci j. A ty? Wolisz tam zestawiać elementy. [h-i]w meczach regionalnych w Czechach ch:

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

Jeśli więc możesz wymienić zakres elementów zestawiających w wyrażeniu w nawiasie, możesz spodziewać się, że będziesz w stanie również je wymienić osobno. [a-cch]pasowałby do tych elementów zestawiających między ai ca coraz i h. Aby mieć a-ci chelement zestawiający, potrzebujemy nowej składni:

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

(te pośrednie ai coraz chjeden).

Teraz świat nie jest jeszcze idealny i prawdopodobnie nigdy nie będzie. Powyższy przykład dotyczył systemu GNU i działał. Innym przykładem elementu zestawiającego może być ełączenie ostrego akcentu w UTF-8 ( $'e\u0301'renderowane jak $'\u00e9'jako é).

é i é są tym samym znakiem, z tym że jeden jest reprezentowany przez jeden znak, a drugi przez dwa.

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

Będzie działał poprawnie na niektórych systemach, ale nie na innych (na przykład nie na GNU). I nie jest jasne, czy $'[[.\ue9.]]'powinno pasować tylko $'\ue9'czy jedno $'\ue9'i drugie i $'e\u301'.

Nie wspominając o skryptach niealfabetycznych lub skryptach o różnych regionalnych porządkach sortowania, takich jak ffi ( ffiw jednym znaku), które stają się trudne do obsługi przy tak prostym interfejsie API.

Stéphane Chazelas
źródło
1

Jest to przydatne, gdy używane są znaki w języku innym niż angielski (non-ascii). Wspomniany przykład chto digrafat , tj. Niektóre języki mają literę w swoim alfabecie, która jest / może być reprezentowana przez dwie litery w alfabecie angielskim.

Kiedy używasz wyrażenia regularnego [.ch.], w zasadzie mówisz: „Spodziewam się innej niż angielska sekwencji wprowadzania z digrafem ch. Chcę, aby mój chwyrażenie regularne pasowało do pojedynczego znaku . Mój język programowania / silnik regex / klawiatura nie pozwala mi pisać tego digrafu znak, więc piszę [.ch.]. Nie mam na myśli, cpo którym następuje h. Proszę znaleźć zdarzenia z wykopaliskami jako pojedynczym postacią. ”

[[.ch.]]oznacza, że ​​digraf jest częścią zestawu znaków. W tym przypadku właściwie tylko jedna postać. Po prostu standardowa notacja regularna.

Rolf
źródło
Z odpowiedzi Stephane'a wynika , że tak naprawdę ch są to dwie różne postacie; jest on traktowany jako jeden do celów sortowania. Czy na pewno termin „digraf” jest terminem stosowanym?
Wildcard,