GNU/Linux >> Belajar Linux >  >> Linux

Apakah (harus) Lc_collate Mempengaruhi Rentang Karakter?

Urutan pengumpulan melalui LC_COLLATE mendefinisikan tidak hanya urutan karakter individu, tetapi juga arti rentang karakter. Atau apakah itu? Perhatikan cuplikan berikut:

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

Secara intuitif, B tidak ada di [a-z] , jadi ini seharusnya tidak menghasilkan apa pun. Itulah yang terjadi di Ubuntu 8.04 atau 10.04. Tetapi pada beberapa mesin yang menjalankan Debian lenny atau Squeeze, B ditemukan, karena rentang a-z mencakup semua yang ada di antara a dan z dalam urutan susunan, termasuk huruf kapital B melalui Z .

Semua sistem yang diuji memiliki en_US lokal yang dihasilkan. Saya juga mencoba memvariasikan lokal:pada mesin di mana B cocok di atas, hal yang sama terjadi di setiap lokal yang tersedia (kebanyakan berbasis latin:{en_{AU,CA,GB,IE,US},fr_FR,it_IT,es_ES,de_DE}{iso8859-1,iso8859-15,utf-8} , juga lokal Cina) kecuali Jepang (dalam penyandian apa pun yang tersedia) dan C /POSIX .

Apa yang dimaksud dengan rentang karakter dalam ekspresi reguler , ketika Anda melampaui ASCII? Mengapa ada perbedaan antara beberapa instalasi Debian di satu sisi, dan instalasi Debian lainnya dan Ubuntu di sisi lain? Bagaimana sistem lain berperilaku? Siapa yang benar, dan siapa yang seharusnya melaporkan bug?

(Perhatikan bahwa saya secara khusus menanyakan tentang perilaku rentang karakter seperti [a-z] di en_US lokal, terutama pada sistem berbasis GNU libc. Saya tidak bertanya bagaimana cara mencocokkan huruf kecil atau huruf kecil ASCII.)

Pada dua mesin Debian, satu di mana B ada di [a-z] dan yang tidak, output dari LC_COLLATE=en_US locale -k LC_COLLATE adalah

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

dan output dari LC_COLLATE=en_US.utf8 locale -k LC_COLLATE adalah

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

Jawaban yang Diterima:

Jika Anda menggunakan apa pun selain C lokal, Anda tidak boleh menggunakan rentang seperti [a-z] karena ini bergantung pada lokal dan tidak selalu memberikan hasil yang Anda harapkan. Selain masalah kasus yang telah Anda temui, beberapa lokal memperlakukan karakter dengan diakritik (mis. á ) sama dengan karakter dasar (yaitu a ).

Sebagai gantinya, gunakan kelas karakter bernama:

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

Ini akan selalu memberikan hasil yang benar untuk lokal. Namun, Anda harus memilih lokal untuk mencerminkan arti dari teks input dan tes yang Anda coba terapkan.

Terkait:Php:imagechar — Menggambar karakter secara horizontal

Misalnya, jika Anda perlu mencari nilai byte tertentu, gunakan C lokal, yang selalu tersedia:

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

Jika ini tidak berfungsi seperti yang diharapkan, itu benar-benar bug.


Linux
  1. Apa?

  2. Apakah Lvm Mempengaruhi Kinerja?

  3. Apa itu Exec 3?

  1. Linux – Mengapa Es_mx Lokal Bekerja Tapi Tidak Es?

  2. Apa yang Digema $? Mengerjakan??

  3. Apakah “concurrency_level=x” Mempengaruhi Semua Kompilasi yang Dibuat Dengan Make?

  1. Mengapa Ekspresi Reguler Bekerja Di X Tapi Tidak Di Y?

  2. Apa yang Dilakukan "lc_all=c"?

  3. Apa itu PIPEDA pada tahun 2022 dan Bagaimana Pengaruhnya terhadap Penyedia Hosting?