Tentang serakah vs tidak serakah
Pengulangan dalam regex secara default serakah : mereka mencoba mencocokkan repetisi sebanyak mungkin, dan ketika ini tidak berhasil dan mereka harus mundur, mereka mencoba untuk mencocokkan satu repetisi lebih sedikit pada satu waktu, sampai kecocokan dari keseluruhan pola ditemukan. Akibatnya, ketika pertandingan akhirnya terjadi, pengulangan serakah akan cocok sebagai banyak repetisi sebanyak mungkin.
The ?
as a repetition quantifier mengubah perilaku ini menjadi tidak serakah , juga disebut enggan ( misalnya di Java ) (dan terkadang "malas"). Sebaliknya, pengulangan ini pertama-tama akan mencoba mencocokkan pengulangan sesedikit mungkin, dan ketika ini tidak berhasil dan mereka harus mundur, mereka mulai mencocokkan satu reptil lagi. Akibatnya, ketika pertandingan akhirnya terjadi, pengulangan yang enggan akan cocok dengan pengulangan sesedikit mungkin.
Referensi
Contoh 1: Dari A ke Z
Mari kita bandingkan dua pola ini: A.*Z
dan A.*?Z
.
Diberikan masukan berikut:
eeeAiiZuuuuAoooZeeee
Pola menghasilkan kecocokan berikut:
Pertama mari kita fokus pada apa A.*Z
. Ketika cocok dengan yang pertama A
, yang .*
, menjadi serakah, pertama mencoba untuk mencocokkan sebanyak .
mungkin.
eeeAiiZuuuuAoooZeeee
\_______________/
A.* matched, Z can't match
Karena Z
tidak cocok, mesin mundur, dan .*
kemudian harus cocok satu lebih sedikit .
:
eeeAiiZuuuuAoooZeeee
\______________/
A.* matched, Z still can't match
Ini terjadi beberapa kali lagi, sampai akhirnya kita sampai pada ini:
eeeAiiZuuuuAoooZeeee
\__________/
A.* matched, Z can now match
Sekarang Z
bisa cocok, jadi pola keseluruhan cocok:
eeeAiiZuuuuAoooZeeee
\___________/
A.*Z matched
Sebaliknya, pengulangan enggan di A.*?Z
pertandingan pertama sesedikit .
mungkin, dan kemudian mengambil lebih banyak .
bila perlu. Ini menjelaskan mengapa ia menemukan dua kecocokan dalam masukan.
Berikut adalah representasi visual dari apa yang cocok kedua pola tersebut:
eeeAiiZuuuuAoooZeeee
\__/r \___/r r = reluctant
\____g____/ g = greedy
Contoh: Alternatif
Dalam banyak aplikasi, dua kecocokan pada input di atas adalah yang diinginkan, sehingga .*?
digunakan enggan .*
untuk mencegah overmatching. Untuk pola khusus ini, bagaimanapun, ada alternatif yang lebih baik, menggunakan kelas karakter yang dinegasikan.
Pola tersebut A[^Z]*Z
juga menemukan dua kecocokan yang sama dengan A.*?Z
pola untuk input di atas ( seperti yang terlihat di ideone.com ). [^Z]
adalah apa yang disebut kelas karakter yang dinegasikan : ia cocok dengan apa pun kecuali Z
.
Perbedaan utama antara kedua pola tersebut adalah dalam performanya: karena lebih ketat, kelas karakter yang dinegasikan hanya dapat mencocokkan satu cara untuk masukan yang diberikan. Tidak masalah jika Anda menggunakan pengubah serakah atau enggan untuk pola ini. Faktanya, dalam beberapa rasa, Anda dapat melakukan lebih baik lagi dan menggunakan apa yang disebut pembilang posesif, yang tidak mundur sama sekali.
Referensi
Contoh 2: Dari A ke ZZ
Contoh ini harus ilustratif: ini menunjukkan bagaimana pola kelas karakter serakah, enggan, dan dinegasikan cocok secara berbeda dengan input yang sama.
eeAiiZooAuuZZeeeZZfff
Ini adalah kecocokan untuk masukan di atas:
Berikut adalah representasi visual dari apa yang mereka cocokkan:
___n
/ \ n = negated character class
eeAiiZooAuuZZeeeZZfff r = reluctant
\_________/r / g = greedy
\____________/g
topik-topik terkait
Ini adalah tautan ke pertanyaan dan jawaban di stackoverflow yang mencakup beberapa topik yang mungkin menarik.
Satu pengulangan serakah bisa melebihi yang lain