Untuk perhatian Anda, kami mempersembahkan terjemahan panduan singkat ekspresi reguler di Java, yang ditulis oleh Jeff Friesen untuk situs web
javaworld . Untuk kemudahan membaca, kami telah membagi artikel menjadi beberapa bagian.
Ekspresi Reguler di Java, Bagian 1
Menggabungkan beberapa rentang |
Anda dapat menggabungkan beberapa rentang menjadi satu kelas karakter rentang dengan menempatkannya secara berdampingan. Misalnya, kelas [a-zA-Z] mencocokkan semua karakter alfabet Latin dalam huruf kecil atau besar. |
Menggabungkan beberapa rentang
Anda dapat menggabungkan beberapa rentang menjadi satu kelas karakter rentang dengan menempatkannya secara berdampingan. Misalnya, kelas
[a-zA-Z]
mencocokkan semua karakter alfabet Latin dalam huruf kecil atau besar.
Menggabungkan Kelas Karakter
Gabungan kelas karakter terdiri dari beberapa kelas karakter yang disarangkan dan cocok dengan semua karakter dalam gabungan yang dihasilkan. Misalnya, kelas
[a-d[m-p]]
mencocokkan karakter dari
a
ke
d
dan dari
m
ke
p
. Perhatikan contoh berikut:
java RegexDemo [ab[c-e]] abcdef
Contoh ini akan menemukan karakter
a
,
b
,
c
,
d
dan
e
, yang memiliki kecocokan di
abcdef
:
regex = [ab[c-e]]
input = abcdef
Found [a] starting at 0 and ending at 0
Found [b] starting at 1 and ending at 1
Found [c] starting at 2 and ending at 2
Found [d] starting at 3 and ending at 3
Found [e] starting at 4 and ending at 4
Persimpangan kelas karakter
Persimpangan kelas karakter terdiri dari karakter umum untuk semua kelas bersarang dan hanya cocok dengan karakter umum. Misalnya, kelas
[a-z&&[d-f]]
cocok dengan karakter
d
,
e
dan
f
. Perhatikan contoh berikut:
java RegexDemo "[aeiouy&&[y]]" party
Perhatikan bahwa pada sistem operasi Windows saya, tanda kutip ganda diperlukan karena shell perintah memperlakukannya
&
sebagai pemisah perintah. Contoh ini hanya akan menemukan karakter
y
yang memiliki kecocokan pada
party
:
regex = [aeiouy&&[y]]
input = party
Found [y] starting at 4 and ending at 4
Mengurangi kelas karakter
Pengurangan kelas karakter terdiri dari semua karakter kecuali yang terdapat dalam kelas karakter bertumpuk, dan hanya mencocokkan karakter yang tersisa. Misalnya, kelas
[a-z&&[^m-p]]
mencocokkan karakter dari
a
ke
l
dan dari
q
ke
z
:
java RegexDemo "[a-f&&[^a-c]&&[^e]]" abcdefg
Contoh ini akan menemukan karakter
d
dan
f
yang ada kecocokannya di
abcdefg
:
regex = [a-f&&[^a-c]&&[^e]]
input = abcdefg
Found [d] starting at 3 and ending at 3
Found [f] starting at 5 and ending at 5
Kelas Karakter yang Telah Ditentukan Sebelumnya
Beberapa kelas karakter cukup sering muncul dalam
ekspresi reguler untuk membenarkan penggunaan notasi steno. Kelas ini
Pattern
menawarkan kelas karakter yang telah ditentukan sebelumnya sebagai singkatan tersebut. Anda dapat menggunakannya untuk menyederhanakan ekspresi reguler dan meminimalkan kesalahan sintaksis. Ada beberapa kategori kelas karakter yang telah ditentukan sebelumnya:
java.lang.Character
properti standar, POSIX, dan Unicode seperti skrip, blok, kategori, dan biner. Daftar berikut hanya menampilkan kategori kelas standar:
\d
: Nomor. Setara [0-9]
.
\D
: Karakter non-numerik. Setara [^0-9]
.
\s
: Karakter spasi putih. Setara [ \t\n\x0B\f\r]
.
\S
: Bukan karakter spasi. Setara [^\s]
.
\w
: Simbol pembentuk kata. Setara [a-zA-Z_0-9]
.
\W
: Bukan karakter pembentuk kata. Setara [^\w]
.
Contoh berikut menggunakan kelas karakter yang telah ditentukan sebelumnya
\w
untuk mendeskripsikan semua karakter kata dalam teks masukan:
java RegexDemo \w "aZ.8 _"
Perhatikan baik-baik hasil eksekusi berikut, yang menunjukkan bahwa karakter titik dan spasi tidak dianggap sebagai karakter kata:
regex = \w
input = aZ.8 _
Found [a] starting at 0 and ending at 0
Found [Z] starting at 1 and ending at 1
Found [8] starting at 3 and ending at 3
Found [_] starting at 5 and ending at 5
Pemisah garis |
Dokumentasi SDK kelas Pattern menjelaskan metakarakter titik sebagai kelas karakter yang telah ditentukan sebelumnya yang cocok dengan karakter apa pun kecuali pemisah garis (urutan satu atau dua karakter yang menandai akhir baris). Pengecualiannya adalah mode dotall (yang akan kita bahas selanjutnya), di mana titik-titik juga cocok dengan pemisah garis. Kelas Pattern membedakan pemisah garis berikut:
- karakter pengangkutan kembali (
\r );
- karakter baris baru (simbol untuk memajukan kertas satu baris) (
\n );
- karakter pengangkutan kembali segera diikuti oleh karakter baris baru (
\r\n );
- karakter baris berikutnya (
\u0085 );
- karakter pemisah baris (
\u2028 );
- simbol pemisah paragraf (
\u2029 )
|
Kelompok yang ditangkap
Grup penangkap digunakan untuk menyimpan kumpulan karakter yang ditemukan untuk digunakan lebih lanjut saat mencari berdasarkan pola. Konstruk ini merupakan rangkaian karakter yang diapit metakarakter dengan tanda kurung (
( )
). Semua karakter dalam grup yang ditangkap dianggap sebagai satu kesatuan saat mencari berdasarkan pola. Misalnya, grup penangkap (
Java
) menggabungkan huruf
J
,
a
,
v
dan
a
menjadi satu kesatuan. Grup tangkapan ini menemukan semua kemunculan pola
Java
dalam teks masukan. Dengan setiap kecocokan, karakter yang disimpan sebelumnya
Java
akan diganti dengan karakter berikutnya. Grup yang ditangkap dapat disarangkan ke dalam grup lain yang ditangkap. Misalnya, dalam ekspresi reguler,
(Java( language))
grup
(language)
disarangkan di dalam grup
(Java)
. Setiap grup tangkapan yang disarangkan atau tidak disarang diberi nomor, dimulai dari 1, dan penomorannya dimulai dari kiri ke kanan. Pada contoh sebelumnya,
(Java( language))
cocokkan grup tangkap nomor 1 dan
(language)
cocokkan dengan grup tangkap nomor 2. Dalam ekspresi reguler
(a)(b)
,
(a)
cocokkan grup tangkap nomor 1 dan
(b)
grup tangkap nomor 2.
Kecocokan yang disimpan oleh grup tangkapan nantinya dapat diakses menggunakan referensi balik. Ditentukan sebagai karakter garis miring terbalik diikuti dengan karakter numerik yang sesuai dengan jumlah grup yang diambil, referensi balik memungkinkan Anda merujuk ke karakter dalam teks yang diambil oleh grup. Memiliki tautan balik menyebabkan pencocokan merujuk pada hasil pencarian tersimpan grup yang ditangkap berdasarkan nomornya, dan kemudian menggunakan karakter dari hasil tersebut untuk mencoba pencarian lebih lanjut. Contoh berikut menunjukkan penggunaan referensi balik untuk menemukan kesalahan tata bahasa dalam teks:
java RegexDemo "(Java( language)\2)" "The Java language language"
Contoh ini
(Java( language)\2)
menggunakan ekspresi reguler untuk menemukan kesalahan tata bahasa dengan kata duplikat
language
yang langsung mengikuti
Java
teks masukan
"The Java language language"
. Ekspresi reguler ini menentukan dua grup yang akan diambil: nomor 1 –
(Java( language)\2)
, sesuai dengan
Java language language
dan nomor 2 –
(language)
, sesuai dengan karakter spasi yang diikuti oleh
language
. Referensi balik
\2
memungkinkan hasil yang disimpan dari grup nomor 2 untuk ditinjau kembali sehingga pencocokan dapat mencari kemunculan spasi kedua yang diikuti oleh
language
, segera setelah kemunculan spasi pertama dan
language
. Hasil dari matcher tersebut
RegexDemo
adalah sebagai berikut:
regex = (Java( language)\2)
input = The Java language language
Found [Java language language] starting at 4 and ending at 25
Pencocokan batas
Terkadang Anda perlu melakukan pencocokan pola di awal baris, di batas kata, di akhir teks, dll. Anda dapat melakukan ini dengan menggunakan salah satu kelas edge matchers
Pattern
, yang merupakan konstruksi ekspresi reguler yang mencari kecocokan di lokasi berikut:
^
: Awal baris;
$
: Akhir baris;
\b
: Batas kata;
\B
: Batas kata semu;
\A
: Awal teks;
\G
: Akhir pertandingan sebelumnya;
\Z
: Akhir teks, tidak termasuk pemisah baris terakhir (jika ada);
\z
: Akhir teks
Contoh berikut menggunakan
^
metakarakter pencocokan batas untuk menemukan baris yang dimulai dengan
The
, diikuti dengan nol atau lebih karakter kata:
java RegexDemo "^The\w*" Therefore
Karakter
^
menentukan bahwa tiga karakter pertama dari teks masukan harus cocok dengan karakter pola berurutan
T
,
h
dan
e
, yang dapat diikuti oleh angka apa pun dari simbol-simbol pembentuk kata. Berikut hasil eksekusinya:
regex = ^The\w*
input = Therefore
Found [Therefore] starting at 0 and ending at 8
Apa yang terjadi jika Anda mengubah baris perintah menjadi
java RegexDemo "^The\w*" " Therefore"
? Tidak ditemukan kecocokan karena
Therefore
teks masukan diawali dengan karakter spasi.
Pertandingan dengan panjang nol
Terkadang, saat bekerja dengan pencocokan tepi, Anda akan menemukan kecocokan dengan panjang nol.
Совпадение нулевой длины
adalah pertandingan yang tidak mengandung karakter apa pun. Hal ini dapat muncul di teks masukan yang kosong, di awal teks masukan, setelah karakter terakhir teks masukan, dan di antara dua karakter teks masukan. Pertandingan zero-length mudah dikenali karena selalu dimulai dan diakhiri pada posisi yang sama. Perhatikan contoh berikut:
java RegExDemo \b\b "Java is"
Contoh ini mencari dua batasan kata yang berurutan, dan hasilnya terlihat seperti ini:
regex = \b\b
input = Java is
Found [] starting at 0 and ending at -1
Found [] starting at 4 and ending at 3
Found [] starting at 5 and ending at 4
Found [] starting at 7 and ending at 6
Kami melihat beberapa kecocokan zero-length dalam hasilnya. Posisi akhir di sini kurang satu dari posisi awal, karena
RegexDemo
saya tentukan dalam kode sumber di Listing 1
end() – 1
.
Pengukur
Quantifier adalah konstruksi ekspresi reguler yang secara eksplisit atau implisit mengaitkan suatu pola dengan nilai numerik. Nilai numerik ini menentukan berapa kali mencari pola. Penghitung dibagi menjadi serakah, malas, dan sangat serakah:
- Pembilang serakah (
?
, *
atau +
) dirancang untuk menemukan kecocokan terpanjang. Bolehkah saya bertanya X
? untuk menemukan satu atau kurang kejadian X
, X*
untuk menemukan nol atau lebih kejadian X
, X+
untuk menemukan satu atau lebih kejadian X
, X{n}
untuk menemukan n
kejadian X
, X{n,}
untuk menemukan setidaknya (dan mungkin lebih) n
kejadian , X
dan X{n,m}
untuk menemukan setidaknya n
tetapi tidak lebih banyak m
kejadian X
.
- Pembilang malas (
??
, *?
atau +?
) dirancang untuk menemukan kecocokan terpendek. Anda dapat menentukan X??
untuk mencari satu atau kurang kemunculan X
, X*
? untuk menemukan nol atau lebih kejadian X
, X+?
untuk menemukan satu atau lebih kejadian X
, X{n}?
untuk menemukan n
kejadian X
, X{n,}?
untuk menemukan setidaknya (dan mungkin lebih) n
kejadian X
, dan X{n,m}?
untuk menemukan setidaknya n
tetapi tidak lebih dari m
kejadian X
.
- Pembilang super serakah (
?+
, *+
atau ++
) mirip dengan pembilang serakah, hanya saja pembilang super serakah hanya melakukan satu upaya untuk menemukan kecocokan terlama, sedangkan pembilang serakah dapat melakukan beberapa kali percobaan. Dapat diatur X?+
untuk menemukan satu atau kurang kejadian X
, X*+
untuk menemukan nol atau lebih kejadian X
, X++
untuk menemukan satu atau lebih kejadian X
, X{n}+
untuk menemukan n
kejadian X
, X{n,}+
untuk menemukan setidaknya (dan mungkin lebih) n
kejadian , X
dan X{n,m}+
untuk menemukan setidaknya n
tetapi tidak lebih dari m
kejadian X
.
Contoh berikut mengilustrasikan penggunaan bilangan serakah:
java RegexDemo .*ox "fox box pox"
Berikut adalah hasilnya:
regex = .*ox
input = fox box pox
Found [fox box pox] starting at 0 and ending at 10
Penghitung serakah (
.*
) menemukan urutan karakter terpanjang yang diakhiri dengan
ox
. Ini menggunakan seluruh teks masukan dan kemudian memutar kembali hingga mendeteksi bahwa teks masukan diakhiri dengan karakter ini. Sekarang pertimbangkan bilangan malas:
java RegexDemo .*?ox "fox box pox"
Hasilnya:
regex = .*?ox
input = fox box pox
Found [fox] starting at 0 and ending at 2
Found [ box] starting at 3 and ending at 6
Found [ pox] starting at 7 and ending at 10
Pembilang malas (
.*?
) menemukan urutan karakter terpendek yang diakhiri dengan
ox
. Ini dimulai dengan string kosong dan secara bertahap menggunakan karakter hingga menemukan kecocokan. Dan kemudian terus bekerja sampai teks input habis. Terakhir, mari kita lihat bilangan super-serakah:
java RegexDemo .*+ox "fox box pox"
Dan inilah hasilnya:
regex = .*+ox
input = fox box pox
Pembilang ekstra serakah (
.*+
) tidak menemukan kecocokan karena ia menghabiskan semua teks masukan dan tidak ada lagi yang cocok
ox
di akhir ekspresi reguler. Berbeda dengan quantifier serakah, quantifier super serakah tidak melakukan roll back.
Pertandingan dengan panjang nol
Terkadang saat bekerja dengan pembilang, Anda akan menemukan kecocokan dengan panjang nol. Misalnya, penggunaan bilangan serakah berikut akan menghasilkan beberapa kecocokan dengan panjang nol:
java RegexDemo a? abaa
Hasil dari menjalankan contoh ini:
regex = a?
input = abaa
Found [a] starting at 0 and ending at 0
Found [] starting at 1 and ending at 0
Found [a] starting at 2 and ending at 2
Found [a] starting at 3 and ending at 3
Found [] starting at 4 and ending at 3
Ada lima pertandingan hasil eksekusinya. Meskipun huruf pertama, ketiga, dan keempat cukup diharapkan (sesuai dengan posisi tiga huruf
a
di
abaa
), huruf kedua dan kelima mungkin akan mengejutkan Anda. Tampaknya mereka menunjukkan apa
a
yang sesuai
b
dengan akhir teks, namun kenyataannya tidak demikian. Ekspresi reguler
a?
tidak mencari
b
di akhir teks. Ia mencari ada atau tidaknya
a
. Jika
a?
tidak menemukan
a
, ia melaporkannya sebagai kecocokan dengan panjang nol.
Ekspresi bendera bersarang
Pencocokan membuat beberapa asumsi default yang dapat diganti saat mengkompilasi ekspresi reguler menjadi sebuah pola. Kami akan membahas masalah ini nanti. Ekspresi reguler memungkinkan Anda mengganti salah satu default menggunakan ekspresi bendera bertingkat. Konstruksi ekspresi reguler ini ditentukan sebagai metakarakter dalam tanda kurung di sekitar metakarakter tanda tanya (
?
), diikuti dengan huruf Latin kecil. Kelas
Pattern
memahami ekspresi bendera bertingkat berikut:
(?i)
: Mengaktifkan pencocokan pola yang tidak peka huruf besar-kecil. Misalnya saat menggunakan suatu perintah, java RegexDemo (?i)tree Treehouse
urutan karakternya Tree
sesuai dengan polanya tree
. Standarnya adalah pencarian pola peka huruf besar-kecil.
(?x)
: Mengizinkan penggunaan karakter spasi putih dan komentar yang dimulai dengan metakarakter dalam pola #
. Pencocokan akan mengabaikan keduanya. Misalnya untuk java RegexDemo ".at(?x)#match hat, cat, and so on" matter
rangkaian karakter mat
yang cocok dengan polanya .at
. Secara default, karakter spasi putih dan komentar tidak diperbolehkan, dan pencocokan memperlakukannya sebagai karakter yang terlibat dalam pencarian.
(?s)
: Mengaktifkan mode dotall, di mana karakter meta titik cocok dengan pemisah garis selain karakter lainnya. Misalnya, perintah java RegexDemo (?s). \n
akan menemukan karakter baris baru. Standarnya adalah kebalikan dari dotall: tidak ada pemisah garis yang ditemukan. Misalnya, perintah Java RegexDemo . \n
tidak akan menemukan karakter baris baru.
(?m)
: Mengaktifkan mode multiline, yang ^
mencocokkan awal dan $
akhir setiap baris. Misalnya, java RegexDemo "(?m)^abc$" abc\nabc
temukan kedua urutan dalam teks masukan abc
. Secara default, mode satu baris digunakan: ^
mencocokkan awal seluruh teks masukan, dan $
mencocokkan bagian akhir. Misalnya, java RegexDemo "^abc$" abc\nabc
mengembalikan respons bahwa tidak ada kecocokan.
(?u)
: Mengaktifkan penyelarasan huruf besar-kecil yang sensitif terhadap Unicode. Bendera ini, bila digunakan bersama dengan (?i)
, memungkinkan pencocokan pola peka huruf besar-kecil sesuai dengan standar Unicode. Pengaturan defaultnya adalah mencari karakter case-sensitive dan US-ASCII saja.
(?d)
: Mengaktifkan mode string gaya Unix, di mana pencocokan mengenali metakarakter dalam konteks .
, ^
dan $
hanya pemisah baris \n
. Standarnya adalah mode string gaya non-Unix: pencocokan mengenali, dalam konteks metakarakter di atas, semua pembatas baris.
Ekspresi bendera yang disarangkan menyerupai grup yang diambil karena karakternya diapit oleh metakarakter dalam tanda kurung. Berbeda dengan grup yang ditangkap, ekspresi bendera bersarang adalah contoh grup yang tidak ditangkap, yang merupakan konstruksi ekspresi reguler yang tidak menangkap karakter teks. Mereka didefinisikan sebagai rangkaian karakter yang dikelilingi oleh metakarakter dalam tanda kurung.
Menentukan Beberapa Ekspresi Bendera Bersarang |
Dimungkinkan untuk menentukan beberapa ekspresi bendera bertingkat dalam ekspresi reguler dengan menempatkannya berdampingan ( (?m)(?i)) ) atau menempatkan huruf yang mendefinisikannya secara berurutan ( (?mi) ). |
Kesimpulan
Seperti yang mungkin sudah Anda sadari, ekspresi reguler sangat berguna dan menjadi lebih berguna saat Anda menguasai nuansa sintaksisnya. Sejauh ini saya telah memperkenalkan Anda pada dasar-dasar ekspresi reguler dan
Pattern
. Di Bagian 2, kita akan melihat lebih dalam tentang Regex API dan menjelajahi metode
Pattern
,
Matcher
dan
PatternSyntaxException
. Saya juga akan menunjukkan kepada Anda dua aplikasi praktis dari Regex API yang dapat langsung Anda gunakan dalam program Anda.
Ekspresi Reguler di Java, Bagian 3 Ekspresi Reguler di Java, Bagian 4 Ekspresi Reguler di Java, Bagian 5
Apa lagi yang harus dibaca: |
|
GO TO FULL VERSION