Saya mencoba membagi string menjadi dua bagian menggunakan regex. String tersebut diformat sebagai berikut:
text to extract<number>
Saya telah menggunakan (.*?)<
dan <(.*?)>
mana yang berfungsi dengan baik tetapi setelah membaca sedikit ke dalam regex, saya baru saja mulai bertanya-tanya mengapa saya membutuhkan ?
ekspresi dalam. Saya hanya melakukannya seperti itu setelah menemukannya melalui situs ini jadi saya tidak begitu yakin apa bedanya.
Jawaban:
Ini adalah perbedaan antara bilangan serakah dan non-serakah.
Pertimbangkan masukannya
101000000000100
.Menggunakan
1.*1
,*
itu serakah - itu akan cocok sampai akhir, dan kemudian mundur sampai bisa cocok1
, meninggalkan Anda dengan1010000000001
..*?
tidak serakah.*
tidak akan cocok, tetapi kemudian akan mencoba untuk mencocokkan karakter tambahan hingga cocok1
, akhirnya cocok101
.Semua bilangan memiliki mode non-serakah:
.*?
,.+?
,.{2,6}?
, dan bahkan.??
.Dalam kasus Anda, pola yang serupa bisa jadi
<([^>]*)>
- mencocokkan apa pun kecuali tanda yang lebih besar dari (secara tegas, ini cocok dengan nol atau lebih karakter selain>
di antara<
dan>
).Lihat Lembar Cheat Pengukur .
sumber
?
berbeda dari yang tidak serakah??
?"abc"
, regex/\w\w?\w/
akan cocok dengan string lengkap"abc"
- karena?
serakah./\w\w??\w/
malas - itu hanya akan cocok"ab"
. Itu hanya akan mundur dan cocok"abc"
jika gagal nanti.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
danA.*?Z
.Diberikan masukan berikut:
Pola menghasilkan kecocokan berikut:
A.*Z
menghasilkan 1 pertandingan:AiiZuuuuAoooZ
( lihat di rubular.com )A.*?Z
menghasilkan 2 kecocokan:AiiZ
danAoooZ
( lihat di rubular.com )Pertama mari kita fokus pada apa
A.*Z
. Ketika cocok dengan yang pertamaA
, 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 denganA.*?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 kecualiZ
.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.
Ini adalah kecocokan untuk masukan di atas:
A[^Z]*ZZ
menghasilkan 1 kecocokan:AuuZZ
( seperti yang terlihat di ideone.com )A.*?ZZ
menghasilkan 1 kecocokan:AiiZooAuuZZ
( seperti yang terlihat di ideone.com )A.*ZZ
menghasilkan 1 kecocokan:AiiZooAuuZZeeeZZ
( seperti yang terlihat di ideone.com )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
sumber
Katakanlah Anda memiliki:
<a></a>
<(.*)>
akan cocok dia></a
mana<(.*?)>
akan cocoka
. Yang terakhir berhenti setelah pertandingan pertama>
. Ia memeriksa satu atau 0 kecocokan yang.*
diikuti oleh ekspresi berikutnya.Ekspresi pertama
<(.*)>
tidak berhenti saat mencocokkan yang pertama>
. Ini akan berlanjut sampai pertandingan terakhir>
.sumber