GNU/Linux >> Linux Esercitazione >  >> Linux

(dovrebbe) Lc_collate influisce sugli intervalli di caratteri?

Ordine di confronto tramite LC_COLLATE definisce non solo l'ordinamento dei singoli caratteri, ma anche il significato degli intervalli di caratteri. O lo fa? Considera il seguente snippet:

unset LANGUAGE LC_ALL
echo B | LC_COLLATE=en_US grep '[a-z]'

Intuitivamente, B non è in [a-z] , quindi questo non dovrebbe produrre nulla. Questo è ciò che accade su Ubuntu 8.04 o 10.04. Ma su alcune macchine che eseguono Debian lenny o squeeze, B viene trovato, perché l'intervallo a-z include tutto ciò che è compreso tra a e z nell'ordine di confronto, comprese le lettere maiuscole B tramite Z .

Tutti i sistemi testati hanno il en_US locale generato. Ho anche provato a variare la locale:sulle macchine in cui B è abbinato sopra, lo stesso accade in ogni locale disponibile (principalmente in latino:{en_{AU,CA,GB,IE,US},fr_FR,it_IT,es_ES,de_DE}{iso8859-1,iso8859-15,utf-8} , anche le versioni locali cinesi) eccetto il giapponese (in qualsiasi codifica disponibile) e C /POSIX .

Cosa significano gli intervalli di caratteri nelle espressioni regolari , quando vai oltre l'ASCII? Perché c'è una differenza tra alcune installazioni Debian da un lato e altre installazioni Debian e Ubuntu dall'altro? Come si comportano gli altri sistemi? Chi ha ragione e contro chi dovrebbe essere segnalato un bug?

(Nota che sto chiedendo specificamente il comportamento di intervalli di caratteri come [a-z] in en_US locali, principalmente su sistemi basati su GNU libc. Non sto chiedendo come abbinare le lettere minuscole o le lettere minuscole ASCII.)

Su due macchine Debian, una dove B è in [a-z] e uno in cui non lo è, l'output di LC_COLLATE=en_US locale -k LC_COLLATE è

collate-nrules=4
collate-rulesets=""
collate-symb-hash-sizemb=1
collate-codeset="ISO-8859-1"

e l'output di LC_COLLATE=en_US.utf8 locale -k LC_COLLATE è

collate-nrules=4
collate-rulesets=""
collate-symb-hash-sizemb=2039
collate-codeset="UTF-8"

Risposta accettata:

Se stai usando qualcosa di diverso da C locale, non dovresti usare intervalli come [a-z] poiché questi dipendono dalla località e non sempre danno i risultati che ti aspetteresti. Oltre al problema del caso che hai già riscontrato, alcune impostazioni locali trattano i caratteri con segni diacritici (ad es. á ) lo stesso del carattere di base (cioè a ).

Invece, usa una classe di caratteri denominata:

echo B | grep '[[:lower:]]'

Questo darà sempre il risultato corretto per la locale. Tuttavia, devi scegliere la lingua in modo che rifletta il significato sia del testo di input che del test che stai cercando di applicare.

Correlati:Php:imagechar — Disegna un carattere orizzontalmente

Ad esempio, se hai bisogno di trovare un valore di byte particolare, usa il C locale, sempre disponibile:

echo B | LANG=C grep '[a-z]'

Se questo non funziona come previsto, è davvero un bug.


Linux
  1. Cosa fa "lc_all=c"?

  2. Cosa fa Eco $? Fare??

  3. Che cos'è PIPEDA nel 2022 e in che modo influisce sui provider di hosting?

  4. Cosa dovrei scegliere:GTK+ o Qt?

  5. wc -l NON conta l'ultimo del file se non ha il carattere di fine riga

"concurrency_level=x" ha effetto su tutte le compilazioni realizzate con Make?

Cosa restituisce malloc(0)?

Cosa significa 'cd-'?

Perché wprintf traslittera il testo russo in Unicode in latino su Linux?

In che modo umask influisce sugli ACL?

Devo tentare di "bilanciare" i miei thread o Linux lo fa?