Apa artinya [[.ch.]] Dalam suatu regex?

11

Judul alternatif: Apa itu "collating sequence" atau "collating element" dalam regex yang sesuai dengan POSIX?

Saya menemukan definisi teknis yang tepat di Bagian 9.3.5 dari spesifikasi POSIX , sebagai item # 4 dalam daftar, tetapi tidak terlalu jelas bagi saya.

Saya mencari-cari di web untuk contoh dan penjelasan dan muncul tidak sepenuhnya dengan tangan kosong, tetapi jelas tidak tercerahkan .

Satu-satunya hal yang saya dapatkan adalah bahwa dalam keadaan tertentu, Anda dapat membuat regex Anda memperlakukan beberapa karakter seolah-olah mereka adalah karakter tunggal untuk tujuan perbandingan panjang dan menentukan apa "pertandingan paling lama" (karena regex serakah dan serakah). kembalikan kecocokan terpanjang yang mungkin).

Apakah hanya itu saja? Saya mengalami kesulitan melihat penggunaan untuk itu, tetapi saya menduga pemahaman saya tidak lengkap. Apa yang sebenarnya "menyusun" untuk regex? Dan bagaimana [[.ch.]], contoh dalam spesifikasi POSIX, terkait dengan ini?

Wildcard
sumber

Jawaban:

7

Elemen kolasi biasanya dirujuk dalam konteks penyortiran.

Dalam banyak bahasa, collation (pengurutan seperti dalam kamus) tidak hanya dilakukan per karakter. Misalnya, di Ceko, chtidak memilah antara cgdan ciseperti itu dalam bahasa Inggris, tetapi dianggap sebagai keseluruhan untuk menyortir. Ini adalah elemen penyusun (kita tidak bisa merujuk ke karakter di sini, karakter adalah bagian dari elemen penyusun) yang menyortir di antara hdan i.

Sekarang Anda mungkin bertanya, Apa hubungannya dengan ekspresi reguler? , Mengapa saya ingin merujuk ke elemen penyusun dalam ekspresi braket? .

Nah, di dalam ekspresi braket, orang menggunakan urutan. Misalnya di [c-j], Anda ingin karakter di antara cdan j. Baiklah, kan? Anda lebih suka menyusun elemen di sana. [h-i]dalam pertandingan lokal Republik ch:

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

Jadi, jika Anda dapat membuat daftar berbagai elemen penyusun dalam ekspresi braket, maka Anda berharap dapat membuat daftar mereka secara individual juga. [a-cch]akan cocok dengan elemen penyusun di antara adan cdan cdan hkarakter. Untuk memiliki a-cdan chmenyusun elemen, kita memerlukan sintaks baru:

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

(Yang di antara adan cdan yang ch).

Sekarang, dunia belum sempurna dan mungkin tidak akan pernah. Contoh di atas adalah pada sistem GNU dan berfungsi. Contoh lain dari elemen collating bisa edengan menggabungkan aksen akut di UTF-8 ( $'e\u0301'diterjemahkan seperti $'\u00e9'as é).

é dan é adalah karakter yang sama kecuali satu diwakili dengan satu karakter dan yang lainnya dengan dua.

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

Akan bekerja dengan baik pada beberapa sistem tetapi tidak pada yang lain (bukan yang GNU misalnya). Dan tidak jelas apakah $'[[.\ue9.]]'hanya cocok $'\ue9'atau keduanya $'\ue9'dan $'e\u301'.

Belum lagi skrip non-alfabet, atau skrip dengan urutan yang berbeda, regional, pengurutan, hal-hal seperti ffi ( ffidalam satu karakter) yang menjadi sulit untuk ditangani dengan API sederhana seperti itu.

Stéphane Chazelas
sumber
1

Ini berguna ketika karakter non-Inggris (non-ascii) sedang digunakan. Contoh yang chAnda sebutkan adalah digraf , yaitu beberapa bahasa memiliki huruf dalam alfabet mereka yang / dapat diwakili oleh dua huruf dalam alfabet Inggris.

Ketika Anda menggunakan [.ch.]dalam regexp, Anda pada dasarnya mengatakan: "Saya mengharapkan urutan input non-Inggris dengan digraf ch. Saya ingin regexp saya cocok dengan charachter tunggal ch. Bahasa pemrograman / mesin regex / keyboard saya tidak memungkinkan saya untuk menulis digraf ini. masuk, jadi saya mengetik [.ch.]. Maksud saya bukan cdiikuti oleh h. Harap hanya menemukan kejadian digraph sebagai karakter tunggal. "

[[.ch.]]berarti digraf adalah bagian dari sekumpulan karakter. Dalam hal ini sebenarnya hanya satu karakter. Hanya notasi regexp standar.

Rolf
sumber
Dari jawaban Stephane sepertinya sebenarnya ch adalah dua karakter yang berbeda; itu hanya diperlakukan sebagai satu untuk keperluan penyortiran. Apakah Anda yakin "digraf" adalah istilah yang berlaku?
Wildcard