RegEx: Kecocokan sekecil mungkin atau kecocokan nongreedy

98

Bagaimana cara memberi tahu RegEx (versi .NET) untuk mendapatkan kecocokan valid terkecil, bukan yang terbesar?

Jonathan Allen
sumber

Jawaban:

192

Untuk ekspresi reguler seperti .*atau .+, tambahkan tanda tanya ( .*?atau .+?) untuk mencocokkan karakter sesedikit mungkin. Untuk mencocokkan bagian secara opsional (?:blah)?tetapi tanpa pencocokan kecuali benar-benar diperlukan, gunakan sesuatu seperti (?:blah){0,1}?. Untuk pertandingan berulang (baik menggunakan {n,}atau {n,m}sintaks) tambahkan tanda tanya untuk mencoba mencocokkan sesedikit mungkin (misalnya {3,}?atau {5,7}?).

Dokumentasi tentang bilangan ekspresi reguler juga dapat membantu.

DMI
sumber
7
Saya tidak tahu, apakah saya satu-satunya yang mengalami kesalahpahaman ini, tetapi penting untuk diperhatikan: Meskipun benar bahwa operator yang tidak serakah akan mencocokkan karakter sesedikit mungkin, mungkin masih bukan kecocokan yang dicari untuk. "Karakter sesedikit mungkin" tidak sama dengan "kecocokan sesingkat mungkin" terkait standar RegEx. Lihat jawaban di bawah komentar saya: Dengan abcabkdan a.+?k, RegEx akan mencocokkan seluruh string.
finefoot
Baris2 "tetapi tanpa pencocokan kecuali benar-benar diperlukan": Apa artinya ini?
Hujan
70

Operator yang tidak serakah ?,. Seperti:

.*?
David Hedlund
sumber
45

Operator non serakah tidak berarti pertandingan yang sesingkat mungkin:

abcabk.dll

a.+?k akan cocok dengan seluruh string (dalam contoh ini), bukan hanya tiga tanda terakhir.

Saya ingin benar-benar menemukan kecocokan sekecil mungkin.

Itu adalah kemungkinan kecocokan terakhir untuk ' a' untuk tetap mengizinkan semua kecocokan k.

Saya kira satu-satunya cara untuk melakukannya adalah dengan menggunakan ekspresi seperti:

a[^a]+?k

Jonathan
sumber
2
Atau cari dalam urutan terbalik, dimulai dari akhir, saat kecocokan bertingkat: "(ab (abk) bk)".
LBogaardt
7
@LBogaardt bagaimana cara mencari dalam urutan terbalik? jangan mengerti
azerafati
2
@LBogaardt Masih membuka pertanyaan: Bagaimana cara mencari dalam urutan terbalik? Katakanlah saya ingin mendapatkan cab. Jika masukan saya caaacabdan saya mencarinya a.*?bakan mengembalikan string lengkap, bukan kecocokan pendek di dalamnya. Bagaimana saya menelusuri mundur dari b?
C4d
3
Balikkan string, lalu terapkan regex.
Jonathan Allen
3
Ini sangat membantu. Untuk orang-orang seperti saya yang mencoba memahami apa yang terjadi di sini, bentuk generiknya adalah START[^START]*?END(START dan END adalah regex karakter awal dan akhir Anda). Ini pada dasarnya berarti "mencocokkan apa pun dari MULAI hingga AKHIR di mana karakter di antara tidak menyertakan MULAI lagi"
derekantrican