Dalam artikel Wikipedia tentang ekspresi reguler , tampaknya [[:digit:]]
= [0-9]
= \d
.
Bagaimana keadaan di mana mereka tidak setara? Apa bedanya?
Setelah beberapa penelitian, saya pikir satu perbedaan adalah bahwa ekspresi braket [:expr:]
tergantung lokal.
regular-expression
wildcards
harbinn
sumber
sumber
Jawaban:
Ya, itu
[[:digit:]]
~[0-9]
~\d
(di mana ~ berarti aproksimat).Dalam sebagian besar bahasa pemrograman (jika didukung)
\d
≡[[:digit:]]
(identik).Ini
\d
kurang umum daripada[[:digit:]]
(tidak dalam POSIX tetapi dalam GNUgrep -P
).Ada banyak digit di UNICODE , misalnya:
123456789 # Hindu-Arabic
Angka arab٠١٢٣٤٥٦٧٨٩ # ARABIC-INDIC
۰۱۲۳۴۵۶۷۸۹ # EXTENDED ARABIC-INDIC/PERSIAN
߀߁߂߃߄߅߆߇߈߉ # NKO DIGIT
०१२३४५६७८९ # DEVANAGARI
Semuanya dapat dimasukkan dalam
[[:digit:]]
atau\d
.Sebaliknya,
[0-9]
umumnya hanya angka ASCII0123456789
.Ada banyak bahasa: Perl, Java, Python, C. Di mana
[[:digit:]]
(dan\d
) panggilan untuk makna yang diperluas. Misalnya, kode perl ini akan cocok dengan semua digit dari atas:Yang setara dengan memilih semua karakter yang memiliki properti Unicode
Numeric
dandigits
:Grep mana yang dapat mereproduksi (versi spesifik pcre mungkin memiliki daftar internal yang berbeda dari poin kode numerik dari Perl):
Ubah ke [0-9] untuk melihat:
POSIX
Untuk POSIX BRE atau ERE tertentu:
Tidak
\d
didukung (tidak dalam POSIX tetapi dalam GNUgrep -P
).[[:digit:]]
diperlukan oleh POSIX agar sesuai dengan kelas karakter digit, yang pada gilirannya diwajibkan oleh ISO C untuk menjadi karakter 0 hingga 9 dan tidak ada yang lain. Jadi hanya dalam C locale semua[0-9]
,[0123456789]
,\d
dan[[:digit:]]
berarti persis sama. Tidak[0123456789]
ada kemungkinan salah tafsir,[[:digit:]]
tersedia dalam lebih banyak utilitas dan itu umum untuk berarti saja[0123456789]
. Ini\d
didukung oleh beberapa utilitas.Adapun
[0-9]
, arti dari range range hanya didefinisikan oleh POSIX di C locale; di lokal lain mungkin berbeda (mungkin urutan codepoint atau urutan pemeriksaan atau sesuatu yang lain).kerang
Beberapa implementasi mungkin memahami rentang untuk menjadi sesuatu yang berbeda dari pesanan ASCII biasa (ksh93 misalnya):
Dan itu adalah sumber bug yang menunggu untuk terjadi.
sumber
iswctype()
dan BRE / ERE / wildcard dalam utilitas POSIX, [0-9] dan [[: digit:]] hanya cocok dengan 0123456789. Dan itu akan dibuat eksplisit dalam revisi standar berikutnyaperl
itu\d
dalam mode Unicode cocok dengan angka desimal dari skrip lain. Terima kasih untuk itu. Dengan PCRE, lihat(*UCP)
seperti di GNUgrep -Po '(*UCP)\d'
ataugrep -Po '(*UCP)[[:digit:]]
untuk kelas yang didasarkan pada properti Unicode.[:digit:]
sintaks akan menyarankan Anda ingin menggunakan pelokalan, itulah yang dianggap pengguna sebagai angka. Saya tidak pernah menggunakan[:digit:]
karena dalam praktiknya sama dengan[0-9]
dan dalam kasus apa pun, selalu saya ingin mencocokkan pada 0123456789, saya tidak pernah bermaksud untuk mencocokkan٠١٢٣٤٥٦٧٨٩
, dan saya tidak dapat memikirkan kasus penggunaan di mana orang ingin mencocokkan dengan angka desimal. dalam skrip apa pun dengan utilitas POSIX. Lihat juga diskusi saat ini tentang[:blank:]
di zsh ML . Kelas-kelas karakter itu agak berantakan.Ini tergantung pada bagaimana Anda mendefinisikan angka;
[0-9]
cenderung hanya yang ASCII (atau mungkin sesuatu yang bukan ASCII atau superset ASCII tetapi 10 digit yang sama seperti di ASCII hanya dengan representasi bit yang berbeda (EBCDIC));\d
di sisi lain bisa berupa digit biasa (versi lama dari Perl, atau versi modern dari Perl dengan/a
flag ekspresi reguler diaktifkan) atau bisa juga merupakan pasangan Unicode\p{Digit}
yang lebih merupakan seperangkat digit lebih besar daripada[0-9]
atau/\d/a
cocok.perldoc perlrecharclass
untuk informasi lebih lanjut, atau baca dokumentasi untuk bahasa yang dimaksud untuk melihat bagaimana perilakunya.Tapi tunggu, masih ada lagi! Lokal juga dapat memvariasikan apa yang
\d
cocok, sehingga\d
bisa mencocokkan digit lebih sedikit daripada set Unicode lengkap seperti itu, dan (mudah-mudahan, biasanya) juga termasuk[0-9]
. Ini mirip dengan perbedaan dalam C antaraisdigit(3)
([0-9]
) danisnumber(3)
([0-9
ditambah apa pun dari lokal).Mungkin ada panggilan yang dapat dilakukan untuk mendapatkan nilai digit, meskipun bukan
[0-9]
:sumber
isnumber()
adalah hal yang BSD, setidaknya berdasarkan pada halaman manual sepertinya begitu[0-9]
.Arti berbeda
[0-9]
,[[:digit:]]
dan\d
disajikan dalam jawaban lain. Di sini saya ingin menambahkan perbedaan dalam implementasi mesin regex.Jadi
[[:digit:]]
selalu berhasil ,\d
tergantung. Dalam manual grep disebutkan bahwa[[:digit:]]
hanya ada0-9
diC
lokal.PS1: Jika Anda tahu lebih banyak, silakan rentangkan tabel.
PS2: GNU grep 3.1 dan GNU 4.4 digunakan untuk pengujian.
sumber
grep
dansed
, dengan perbedaan terbesar mungkin antara versi GNU vs yang lain. Jawaban ini mungkin lebih bermanfaat jika disebutkan versi managrep
dansed
merujuknya. Atau apa sumber tabel itu, dalam hal ini. 2) tabel itu mungkin juga ditranskripsi ke teks, karena tidak mengandung apa pun yang mengharuskannya menjadi gambarre
module tidak mendukung [[: digit:]] tetapi add in libraryregex
mendukungnya sehingga saya akan sedikit niggle di selalu berfungsi. Itu selalu berfungsi dalam situasi keluhan posix.Perbedaan teoretis telah dijelaskan dengan cukup baik dalam jawaban lain, jadi tetap menjelaskan perbedaan praktis .
Berikut adalah beberapa kasus penggunaan yang lebih umum untuk mencocokkan angka:
Ekstraksi data sekali pakai
Seringkali, ketika Anda ingin mengelompokkan beberapa angka, angka-angka itu sendiri berada dalam file teks yang diformat dengan canggung. Anda ingin mengekstraknya untuk digunakan dalam program Anda. Anda mungkin dapat mengetahui format angka (dengan melihat file) dan lokal Anda saat ini, jadi tidak apa - apa untuk menggunakan salah satu formulir , selama itu menyelesaikan pekerjaan.
\d
membutuhkan penekanan tombol paling sedikit, sehingga sangat umum digunakan.Sanitasi input
Anda memiliki beberapa input pengguna yang tidak dipercaya (mungkin dari formulir web), dan Anda perlu memastikan itu tidak mengandung kejutan. Mungkin Anda ingin menyimpannya dalam bidang angka dalam basis data, atau menggunakan sebagai parameter perintah shell untuk dijalankan di server. Dalam hal ini, Anda benar-benar menginginkannya
[0-9]
, karena ini adalah yang paling ketat dan dapat diprediksi.Validasi data
Anda memiliki sedikit data yang tidak akan Anda gunakan untuk hal-hal yang "berbahaya", tetapi alangkah baiknya jika Anda tahu itu angka. Misalnya, program Anda memungkinkan pengguna untuk memasukkan alamat, dan Anda ingin menyorot kesalahan ketik yang mungkin jika input tersebut tidak berisi nomor rumah. Dalam hal ini, Anda mungkin ingin menjadi seluas mungkin, begitu
[[:digit:]]
juga cara untuk pergi.Itu tampaknya menjadi tiga kasus penggunaan paling umum untuk pencocokan angka. Jika Anda pikir saya melewatkan yang penting, silakan berikan komentar.
sumber