Saya menulis ekspresi reguler yang berfungsi dengan baik dalam program tertentu (grep, sed, awk, perl, python, ruby, ksh, bash, zsh, find, emacs, vi, vim, gedit, ...). Tetapi ketika saya menggunakannya di program yang berbeda (atau pada varian unix yang berbeda), itu berhenti cocok. Mengapa?
Jawaban yang Diterima:
Sayangnya, karena alasan historis, alat yang berbeda memiliki sintaks ekspresi reguler yang sedikit berbeda, dan terkadang beberapa implementasi memiliki ekstensi yang tidak didukung oleh alat lain. Meskipun ada kesamaan, sepertinya setiap penulis alat membuat beberapa pilihan yang berbeda.
Konsekuensinya adalah jika Anda memiliki ekspresi reguler yang berfungsi di satu alat, Anda mungkin perlu memodifikasinya agar berfungsi di alat lain. Perbedaan utama antara alat-alat umum adalah:
- apakah operator
+?|(){}
memerlukan garis miring terbalik; - ekstensi apa yang didukung di luar
.[]*^$
dan biasanya+?|()
Dalam jawaban ini, saya mencantumkan standar utama. Periksa dokumentasi alat yang Anda gunakan untuk mengetahui detailnya.
Perbandingan mesin ekspresi reguler Wikipedia memiliki tabel yang mencantumkan fitur yang didukung oleh implementasi umum.
Ekspresi reguler dasar (BRE)
Ekspresi reguler dasar dikodifikasikan oleh standar POSIX. Ini adalah sintaks yang digunakan oleh grep
, sed
dan vi
. Sintaks ini menyediakan fitur berikut:
^
dan$
cocok hanya di awal dan akhir baris..
cocok dengan karakter apa pun (atau karakter apa pun kecuali baris baru).[…]
cocok dengan salah satu karakter yang tercantum di dalam tanda kurung (set karakter). Jika karakter pertama setelah kurung buka adalah^
, karakter yang tidak tercantum akan dicocokkan sebagai gantinya. Untuk memasukkan]
, letakkan segera setelah pembukaan[
(atau setelah[^
jika itu adalah himpunan negatif). Jika-
berada di antara dua karakter, ini menunjukkan rentang; untuk memasukkan-
. literal , letakkan di tempat yang tidak dapat diuraikan sebagai rentang.- Garis miring terbalik sebelum
^$.*[
mengutip karakter berikutnya. *
cocok dengan karakter atau subekspresi sebelumnya 0, 1 kali atau lebih.(…)
adalah grup sintaksis, untuk digunakan dengan*
operator atau referensi balik danDIGIT
pengganti.- Referensi balik
1
,2
, … cocok dengan teks yang sama persis dengan grup yang sesuai, mis.(fo*)(ba*)1
cocok denganfoobaafoo
tapi bukanfoobaafo
. Tidak ada cara standar untuk merujuk ke grup ke-10 dan seterusnya (arti standar10
adalah grup pertama diikuti oleh<
).
Fitur berikut juga standar, tetapi tidak ada dalam beberapa penerapan terbatas:
{m,n}
cocok dengan karakter atau subekspresi sebelumnya antara m ke n waktu; n atau m dapat dihilangkan, dan{m}
berarti persis m .- Di dalam kurung, kelas karakter dapat digunakan, misalnya
[[:alpha:]]
cocok dengan huruf apa pun. Implementasi modern dari ekspresi tanda kurung) juga menyertakan elemen susunan seperti[.ll.]
dan kelas kesetaraan seperti[=a=]
.
Berikut ini adalah ekstensi umum (terutama di alat GNU), tetapi tidak ditemukan di semua implementasi. Periksa manual alat yang Anda gunakan.
|
untuk pergantian:foo|bar
cocok denganfoo
ataubar
.?
(kependekan dari{0,1}
) dan+
(kependekan dari{1,}
) cocok dengan karakter atau subekspresi sebelumnya paling banyak 1 kali, atau setidaknya 1 kali berturut-turut.n
cocok dengan baris baru,t
cocok dengan tab, dll.w
cocok dengan konstituen kata apa pun (kependekan dari[_[:alnum:]]
tetapi dengan variasi dalam hal pelokalan) danW
cocok dengan karakter apa pun yang bukan merupakan konstituen kata.<
dan>
mencocokkan string kosong masing-masing hanya di awal atau akhir kata;b
cocok, danB
cocok denganb
tidak.
Perhatikan bahwa alat tanpa |
operator tidak memiliki kekuatan penuh ekspresi reguler. Referensi balik memungkinkan beberapa hal tambahan yang tidak dapat dilakukan dengan ekspresi reguler dalam arti matematika.
Extended Regular Expression (ERE)
Ekspresi reguler yang diperluas dikodifikasikan oleh standar POSIX. Keuntungan utama mereka atas BRE adalah keteraturan:semua operator standar adalah karakter tanda baca kosong, garis miring terbalik sebelum karakter tanda baca selalu mengutipnya. Ini adalah sintaks yang digunakan oleh awk
, grep -E
atau egrep
, GNU sed -r
, dan bash's =~
operator. Sintaks ini menyediakan fitur berikut:
^
dan$
cocok hanya di awal dan akhir baris..
cocok dengan karakter apa pun (atau karakter apa pun kecuali baris baru).[…]
cocok dengan salah satu karakter yang tercantum di dalam tanda kurung (set karakter). Komplementasi dengan^
initial inisial dan rentang berfungsi seperti di BRE (lihat di atas). Kelas karakter dapat digunakan tetapi hilang dari beberapa implementasi. Implementasi modern juga mendukung kelas kesetaraan dan elemen penyusunan. Garis miring terbalik di dalam tanda kurung mengutip karakter berikutnya di beberapa tetapi tidak semua implementasi; gunakan\
berarti garis miring terbalik untuk portabilitas.(…)
adalah grup sintaksis, untuk digunakan dengan*
atauDIGIT
pengganti.|
untuk pergantian:foo|bar
cocok denganfoo
ataubar
.*
,+
dan?
cocok dengan karakter atau subekspresi sebelumnya beberapa kali:0 atau lebih untuk*
, 1 atau lebih untuk+
, 0 atau 1 untuk?
.- Backslash mengutip karakter berikutnya jika bukan alfanumerik.
{m,n}
cocok dengan karakter atau subekspresi sebelumnya antara m dan n kali (hilang dari beberapa implementasi); n atau m dapat dihilangkan, dan{m}
berarti persis m .- Beberapa ekstensi umum seperti pada BRE:
DIGIT
backreferences (terutama tidak ada dalam awk kecuali dalam implementasi busybox di mana Anda dapat menggunakan$0 ~ "(...)\1"
); karakter khususn
,t
, dll.; batas katab
danB
, konstituen katab
danB
, …
PCRE (ekspresi reguler yang kompatibel dengan Perl)
PCRE adalah ekstensi dari ERE, awalnya diperkenalkan oleh Perl dan diadopsi oleh GNU grep -P
dan banyak alat dan bahasa pemrograman modern , biasanya melalui perpustakaan PCRE. Lihat dokumentasi Perl untuk pemformatan yang bagus dengan contoh. Tidak semua fitur Perl versi terbaru didukung oleh PCRE (mis. Eksekusi kode Perl hanya didukung di Perl). Lihat manual PCRE untuk ringkasan fitur yang didukung. Tambahan utama untuk ERE adalah:
(?:…)
adalah grup yang tidak menangkap:seperti(…)
, tetapi tidak dihitung sebagai referensi balik.(?=FOO)BAR
(lookahead) cocok denganBAR
, tetapi hanya jika ada kecocokan untukFOO
mulai dari posisi yang sama. Ini paling berguna untuk mengaitkan kecocokan tanpa menyertakan teks berikut dalam kecocokan:foo(?=bar)
cocok denganfoo
tetapi hanya jika diikuti olehbar
.(?!FOO)BAR
(lookahead negatif) cocok denganBAR
, tetapi tidak ada kecocokan untukFOO
pada posisi yang sama. Misalnya(?!foo)[a-z]+
cocok dengan kata kecil apa pun yang tidak dimulai denganfoo
;[a-z]+(?![0-9)
cocok dengan kata kecil apa pun yang tidak diikuti oleh angka (jadi difoo123
, cocok denganfo
tapi bukanfoo
).(?<=FOO)BAR
(lihat ke belakang) cocok denganBAR
, tetapi hanya jika itu segera didahului oleh kecocokan untukFOO
.FOO
harus memiliki panjang yang diketahui (Anda tidak dapat menggunakan operator pengulangan seperti*
). Ini paling berguna untuk mengaitkan kecocokan tanpa menyertakan teks sebelumnya dalam kecocokan:(?<=^| )foo
cocok denganfoo
tetapi hanya jika diawali dengan spasi atau awal string.(?<!FOO)BAR
(lihat negatif ke belakang) cocok denganBAR
, tetapi hanya jika tidak segera didahului oleh kecocokan untukFOO
.FOO
harus memiliki panjang yang diketahui (Anda tidak dapat menggunakan operator pengulangan seperti*
). Ini paling berguna untuk mengaitkan kecocokan tanpa menyertakan teks sebelumnya dalam kecocokan:(?<![a-z])foo
cocok denganfoo
tetapi hanya jika tidak didahului dengan huruf kecil.
Emacs
Sintaks Emacs adalah perantara antara BRE dan ERE. Selain Emacs, ini adalah sintaks default untuk -regex
di GNU temukan. Emacs menawarkan operator berikut:
^
,$
,.
,[…]
,*
,+
,?
seperti di ERE(…)
,|
,{…}
,DIGIT
seperti di BRE- lebih banyak urutan huruf miring terbalik;
<
dan>
untuk batas kata; dan lebih banyak lagi di versi terbaru Emacs, yang sering kali tidak didukung di mesin lain dengan sintaks mirip Emacs.
Gumpalan cangkang
Gumpalan shell (wildcard) melakukan pencocokan pola dengan sintaks yang benar-benar berbeda dari ekspresi reguler dan kurang kuat. Selain shell, wildcard ini tersedia dengan alat lain seperti find -name
dan filter rsync. Pola POSIX mencakup fitur berikut:
?
cocok dengan satu karakter apa pun.[…]
adalah kumpulan karakter seperti pada sintaks ekspresi reguler umum. Beberapa shell tidak mendukung kelas karakter. Beberapa shell membutuhkan!
bukannya^
untuk meniadakan himpunan.*
cocok dengan urutan karakter apa pun (seringkali kecuali/
saat mencocokkan jalur file; jika/
dikecualikan dari*
, lalu**
terkadang menyertakan/
, tetapi periksa dokumentasi alat).- Backslash mengutip karakter berikutnya.
Ksh menawarkan fitur tambahan yang memberikan polanya yang cocok dengan kekuatan penuh ekspresi reguler. Fitur-fitur ini juga tersedia di bash setelah menjalankan shopt -s extglob
. Zsh memiliki sintaks yang berbeda tetapi juga dapat mendukung sintaks ksh setelah setopt ksh_glob
.