Cosa significa [[.ch.]] In una regex?


11

Titolo alternativo: Che cos'è una "sequenza di confronto" o "elemento di confronto" in una regex conforme a POSIX?

Ho trovato l'esatta definizione tecnica nella Sezione 9.3.5 delle specifiche POSIX , come l'articolo n. 4 nell'elenco, ma non mi è molto chiaro.

Ho cercato su Internet sul web per esempi e spiegazioni e sono venuto fuori non completamente a mani vuote, ma sicuramente non illuminato .

L'unica cosa che ho ottenuto è che in determinate circostanze, puoi far sì che il tuo regex tratti più personaggi come se fossero un singolo personaggio ai fini del confronto della lunghezza e determinare quale sia la "corrispondenza più lunga" (poiché i regex sono avidi e restituisce la corrispondenza più lunga possibile).

Tutto qui, però? Sto riscontrando problemi nel vederne un uso, ma sospetto che la mia comprensione sia incompleta. Cosa sta realmente "confrontando" per una regex? E come si collega [[.ch.]]l'esempio nelle specifiche POSIX?

Risposte:


7

Gli elementi di fascicolazione sono generalmente indicati nel contesto dell'ordinamento.

In molte lingue, le regole di confronto (ordinamento come in un dizionario) non vengono eseguite solo per carattere. Ad esempio, in ceco, chnon ordina tra cge cicome se fosse in inglese, ma è considerato come un tutto per l'ordinamento. È un elemento di confronto (qui non possiamo fare riferimento a un personaggio, il personaggio è un sottoinsieme di elementi di confronto) che si divide tra he i.

Ora potresti chiedere: cosa c'entra questo con le espressioni regolari? , Perché dovrei voler fare riferimento a un elemento di confronto in un'espressione di parentesi? .

Bene, all'interno delle espressioni tra parentesi, si usa l'ordine. Ad esempio in [c-j], vuoi i caratteri tra ce j. Bene, vero? Preferiresti raccogliere elementi lì. [h-i]in una locale ceca corrisponde ch:

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

Quindi, se sei in grado di elencare una serie di elementi di fascicolazione in un'espressione di parentesi, ti aspetteresti di essere in grado di elencarli anche singolarmente. [a-cch]corrisponderebbe agli elementi di confronto tra ae ce i caratteri ce h. Per avere a-ce l' chelemento di confronto, abbiamo bisogno di una nuova sintassi:

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

(quelli tra ae ce chquello).

Ora, il mondo non è ancora perfetto e probabilmente non lo sarà mai. L'esempio sopra era su un sistema GNU e ha funzionato. Un altro esempio di un elemento di confronto potrebbe essere econ un accento acuto combinato in UTF-8 ( $'e\u0301'reso simile $'\u00e9'a é).

é ed é hanno lo stesso personaggio, tranne per il fatto che uno è rappresentato con un personaggio e l'altro con due.

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

Funzionerà correttamente su alcuni sistemi ma non su altri (non quelli GNU per esempio). E non è chiaro se $'[[.\ue9.]]'debba corrispondere solo $'\ue9'o entrambi $'\ue9'e $'e\u301'.

Per non parlare degli script non alfabetici, o degli script con differenti, regionali, ordinamenti, cose come ffi ( ffiin un carattere) che diventano difficili da gestire con un'API così semplice.


1

Ciò è utile quando sono in uso caratteri non inglesi (non ascii). L'esempio chche menzioni è un digrafo , cioè alcune lingue hanno una lettera nel loro alfabeto che è / può essere rappresentata da due lettere in un alfabeto inglese.

Quando usi [.ch.]un regexp, in pratica dici: "Mi aspetto una sequenza di input non inglese con il digraph ch. Voglio che il mio regexp corrisponda al singolo carattere ch. Il mio linguaggio di programmazione / motore regex / tastiera non mi consente di scrivere questo digraph segno, quindi scrivo [.ch.]. Non intendo un cseguito da un h. Si prega di trovare solo le occorrenze del digraph come un singolo carattere. "

[[.ch.]]significa che il digraph fa parte di un insieme di caratteri. In questo caso in realtà solo un personaggio. Solo notazione regexp standard.


Dalla risposta di Stephane sembra che ch è in realtà due diversi personaggi; è solo trattato come uno ai fini dell'ordinamento. Sei sicuro che "digraph" è un termine applicabile?
Wildcard il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.