Anda tidak akan menjadi orang pertama yang kabur tentang hal itu. Inilah yang dikatakan oleh Jeffrey Friedl yang terkenal tentang hal itu (halaman 437+):
Bergantung pada pandangan Anda, itu menambah dimensi baru yang menarik pada hasil pertandingan, atau menambah kebingungan dan kembung.
Dan selanjutnya:
Perbedaan utama antara objek Grup dan objek Capture adalah bahwa setiap objek Grup berisi koleksi Capture yang mewakili semua pertandingan perantara oleh grup selama pertandingan, serta teks akhir yang cocok dengan grup.
Dan beberapa halaman kemudian, inilah kesimpulannya:
Setelah melewati dokumentasi .NET dan benar-benar memahami apa yang ditambahkan objek-objek ini, saya merasa campur aduk tentangnya. Di satu sisi, ini merupakan inovasi yang menarik [..] di sisi lain, tampaknya menambah beban efisiensi [..] dari fungsi yang tidak akan digunakan dalam sebagian besar kasus
Dengan kata lain: mereka sangat mirip, tetapi sesekali dan ketika itu terjadi, Anda akan menemukan kegunaan untuk mereka. Sebelum Anda menumbuhkan jenggot kelabu lain, Anda bahkan mungkin menyukai Capture ...
Karena tidak ada jawaban di atas, atau apa yang dikatakan di pos lain yang benar-benar menjawab pertanyaan Anda, pertimbangkan yang berikut ini. Pikirkan Capture sebagai semacam pelacak sejarah. Ketika regex melakukan kecocokan, ia melewati string dari kiri ke kanan (mengabaikan lompatan mundur sesaat) dan ketika bertemu dengan tanda kurung yang cocok, itu akan menyimpannya dalam $x
(x menjadi digit apa pun), katakanlah $1
.
Mesin regex normal, ketika tanda kurung diulang, akan membuang arus $1
dan akan menggantinya dengan nilai baru. Bukan .NET, yang akan menyimpan riwayat ini dan menempatkannya di Captures[0]
.
Jika kami mengubah regex Anda menjadi seperti berikut:
MatchCollection matches = Regex.Matches("{Q}{R}{S}", @"(\{[A-Z]\})+");
Anda akan melihat bahwa yang pertama Group
akan memiliki satu Captures
(grup pertama selalu menjadi seluruh pertandingan, yaitu, sama dengan $0
) dan grup kedua akan bertahan {S}
, yaitu hanya grup yang cocok terakhir. Namun, dan inilah tangkapannya, jika Anda ingin menemukan dua tangkapan lainnya, mereka masuk Captures
, yang berisi semua tangkapan perantara untuk {Q}
{R}
dan {S}
.
Jika Anda pernah bertanya-tanya bagaimana Anda bisa mendapatkan dari multi-tangkapan, yang hanya menunjukkan pertandingan terakhir ke masing-masing tangkapan yang jelas-jelas ada dalam string, Anda harus menggunakan Captures
.
Kata terakhir pada pertanyaan terakhir Anda: pertandingan total selalu memiliki satu Capture total, jangan campur dengan masing-masing Grup. Capture hanya menarik di dalam grup .
a functionality that won't be used in the majority of cases
Saya pikir dia ketinggalan kapal. Dalam jangka pendek(?:.*?(collection info)){4,20}
meningkatkan efisiensi lebih dari beberapa ratus persen.(?:..)+
. Dengan mudah menyesuaikan apa pun.*?
hingga sub ekspresi tangkap (grup). Lanjutkan. Dalam satu pertandingan, koleksi grup mempercepat berbagai hal yang diperlukan. Tidak perlu mencari berikutnya, tidak ada pintu masuk kembali sehingga 10 hingga 20 kali atau lebih cepat.a functionality that won't be used in the majority of cases
. Bahkan itu adalah fungsi yang paling dicari di tanah regex. Malas / serakah? Apa hubungannya dengan komentar saya? Hal ini memungkinkan memiliki jumlah buffer tangkapan yang bervariasi. Itu dapat menyapu seluruh string dalam satu pertandingan. Jika.*?(dog)
menemukan yang pertamadog
maka(?:.*?(dog))+
akan menemukan semuadog
di seluruh string dalam satu pertandingan. Peningkatan kinerja terlihat.Grup adalah apa yang telah kami kaitkan dengan grup dalam ekspresi reguler
kecuali bahwa ini hanya kelompok 'tertangkap'. Grup yang tidak menangkap (menggunakan sintaks '(?:' Tidak diwakili di sini.
Capture juga merupakan apa yang telah kami kaitkan dengan 'kelompok yang ditangkap'. Tetapi ketika grup diterapkan dengan quantifier beberapa kali, hanya pertandingan terakhir yang disimpan sebagai pertandingan grup. Array menangkap menyimpan semua pertandingan ini.
Adapun pertanyaan terakhir Anda - saya akan berpikir sebelum melihat ini bahwa Capture akan menjadi array dari tangkapan yang dipesan oleh kelompok mereka. Sebaliknya itu hanya alias ke grup [0]. Capture. Cukup tidak berguna ..
sumber
Ini dapat dijelaskan dengan contoh sederhana (dan gambar).
Cocok
3:10pm
dengan ekspresi reguler((\d)+):((\d)+)(am|pm)
, dan menggunakan Mono interaktifcsharp
:Jadi dimana 1?
Karena ada beberapa digit yang cocok dengan grup keempat, kami hanya "mendapatkan" pertandingan terakhir jika kami mereferensikan grup (dengan implisit
ToString()
, yaitu). Untuk mengekspos pertandingan perantara, kita harus masuk lebih dalam dan mereferensikanCaptures
properti pada grup yang dimaksud:Atas perkenan artikel ini .
sumber
Dari dokumentasi MSDN :
sumber
Bayangkan Anda memiliki input teks
dogcatcatcat
dan pola seperti berikutdog(cat(catcat))
Dalam hal ini, Anda memiliki 3 grup, yang pertama ( grup utama ) berhubungan dengan pertandingan.
Cocokkan ==
dogcatcatcat
dan Group0 ==dogcatcatcat
Group1 ==
catcatcat
Group2 ==
catcat
Jadi tentang apa semua ini?
Mari kita pertimbangkan contoh kecil yang ditulis dalam C # (.NET) menggunakan
Regex
kelas.Output :
Mari kita analisis pertandingan pertama (
match0
).Seperti yang Anda lihat ada tiga kelompok kecil :
group3
,group4
dangroup5
Kelompok-kelompok tersebut (3-5) diciptakan karena ' subpattern '
(...)(...)(...)
dari pola utama(dog(cat(...)(...)(...)))
Nilai
group3
korespondensi dengan tangkapannya (capture0
). (Seperti dalam kasusgroup4
dangroup5
). Itu karena tidak ada pengulangan kelompok seperti(...){3}
.Ok, mari kita pertimbangkan contoh lain di mana ada pengulangan grup .
Jika kita mengubah pola ekspresi reguler untuk dicocokkan (untuk kode yang ditunjukkan di atas) dari
(dog(cat(...)(...)(...)))
ke(dog(cat(...){3}))
, Anda akan melihat bahwa ada adalah sebagai berikut kelompok pengulangan :(...){3}
.Sekarang Output telah berubah:
Sekali lagi, mari kita analisis pertandingan pertama (
match0
).Tidak ada lagi grup minor
group4
dangroup5
karena(...){3}
pengulangan ( {n} dimana n> = 2 ) mereka telah digabung menjadi satu grup tunggalgroup3
.Dalam hal ini,
group3
nilainya sesuai dengan itucapture2
( tangkapan terakhir , dengan kata lain).Jadi jika Anda membutuhkan semua 3 menangkap bagian dalam (
capture0
,capture1
,capture2
) Anda harus siklus melalui kelompokCaptures
koleksi.Kesimpulan adalah: perhatikan cara Anda mendesain grup pola Anda. Anda harus berpikir di muka perilaku apa yang menyebabkan spesifikasi, suka
(...)(...)
,(...){2}
atau lainnya(.{3}){2}
.Semoga ini akan membantu menjelaskan perbedaan antara Capture , Grup , dan Pertandingan juga.
sumber