Dalam ekspresi reguler Python, saya menghadapi masalah tunggal ini. Bisakah Anda memberikan instruksi tentang perbedaan antara re.findall('(ab|cd)', string)
dan re.findall('(ab|cd)+', string)
?
import re
string = 'abcdla'
result = re.findall('(ab|cd)', string)
result2 = re.findall('(ab|cd)+', string)
print(result)
print(result2)
Output aktual adalah:
['ab', 'cd']
['cd']
Saya bingung mengapa hasil kedua tidak mengandung 'ab'
juga?
Jawaban:
+
adalah pengukur berulang yang cocok dengan satu atau lebih kali. Di regex(ab|cd)+
, Anda mengulangi grup tangkap(ab|cd)
menggunakan +. Ini hanya akan menangkap iterasi terakhir.Anda dapat mempertimbangkan perilaku ini sebagai berikut:
Katakan string Anda
abcdla
dan regex(ab|cd)+
. Mesin regex akan menemukan kecocokan untuk grup antara posisi 0 dan 1 saatab
keluar dari grup tangkap. Kemudian ia melihat+
quantifier dan mencoba menangkap grup lagi dan akan menangkapcd
antara posisi 2 dan 3.Jika Anda ingin menangkap semua iterasi, Anda harus menangkap grup berulang dengan
((ab|cd)+)
yang cocokabcd
dancd
. Anda dapat membuat grup dalam tidak menangkap karena kami tidak peduli dengan pertandingan grup internal((?:ab|cd)+)
yang cocokabcd
https://www.regular-expressions.info/captureall.html
Dari Documents,
sumber
'(?:ab|cd)+'
akan bekerja.Saya tidak tahu apakah ini akan lebih jelas, tapi mari kita coba bayangkan apa yang terjadi di bawah tenda dengan cara yang sederhana, kita akan menyimpulkan apa yang terjadi dengan menggunakan korek api
findall
cocokkan dan gunakan string pada saat yang bersamaan mari kita bayangkan apa yang terjadi dengan REGEX ini'(ab|cd)'
:Sekarang hal yang sama dengan
'(ab|cd)+'
Saya harap ini membersihkan sedikit.
sumber
Jadi, bagi saya bagian yang membingungkan adalah kenyataan itu
docs
jadi itu mengembalikan Anda bukan pertandingan penuh tetapi hanya pertandingan menangkap. Jika Anda membuat grup ini tidak menangkap
(re.findall('(?:ab|cd)+', string)
, itu akan kembali["abcd"]
seperti yang saya harapkansumber