Pembilang dalam Ekspresi Reguler

Pembilang menentukan berapa banyak contoh karakter, grup, atau kelas karakter yang harus ada dalam input agar kecocokan dapat ditemukan. Tabel berikut mencantumkan kuantifier yang didukung oleh .NET:

Pembilang rakus Pembilang lembam Deskripsi
* *? Cocok dengan nol atau lebih kali.
+ +? Cocok satu atau beberapa kali.
? ?? Cocok dengan nol atau satu kali.
{n} {n}? Cocok tepat n kali.
{n,} {n,}? Cocok setidaknya n kali.
{n,m} {n,m}? Cocok dari n hingga m kali.

Jumlah n dan m merupakan konstanta bilangan bulat. Biasanya, kuantifier adalah serakah. Mereka menyebabkan mesin ekspresi reguler cocok dengan sebanyak mungkin kemunculan pola tertentu. Menambahkan karakter ke ? kuantifier membuatnya malas. Hal ini menyebabkan mesin ekspresi reguler mencocokkan kemunculan sebanyak mungkin. Untuk deskripsi lengkap tentang perbedaan antara kuantifier serakah dan malas, lihat bagian Greedy dan Lazy Quantifiers nanti di artikel ini.

Penting

Kuantifier berlapis, seperti pola (a*)*ekspresi reguler , dapat meningkatkan jumlah perbandingan yang harus dilakukan mesin ekspresi reguler. Jumlah perbandingan dapat meningkat sebagai fungsi eksponensial dari jumlah karakter dalam string input. Untuk informasi selengkapnya tentang perilaku ini dan solusinya, lihat Pelacakan Balik.

Pembilang Ekspresi Reguler

Bagian berikut mencantumkan kuantifier yang didukung oleh ekspresi reguler .NET:

Catatan

Jika karakter *, +, ?, {, dan } ditemui dalam pola ekspresi reguler, mesin ekspresi reguler menafsirkannya sebagai pembilang atau bagian dari konstruksi pembilang kecuali mereka disertakan dalam kelas karakter. Untuk menafsirkan ini sebagai karakter literal di luar kelas karakter, Anda harus melarikan diri dari mereka dengan mendahului mereka dengan garis miring terbalik. Misalnya, string \* dalam pola ekspresi reguler ditafsirkan sebagai karakter tanda bintang harfiah ("*").

Cocokkan Nol atau Lebih Kali: *

Pembilang * cocok dengan elemen sebelumnya nol atau lebih kali. Ini setara dengan kuantifier {0,} . * adalah pembilang rakus yang setara lembam adalah *?.

Contoh berikut menggambarkan ekspresi reguler ini. Lima dari sembilan grup digit dalam string input cocok dengan pola dan empat (95, , 9299219, dan 9919) tidak.

string pattern = @"\b91*9*\b";
string input = "99 95 919 929 9119 9219 999 9919 91119";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);

// The example displays the following output:
//       '99' found at position 0.
//       '919' found at position 6.
//       '9119' found at position 14.
//       '999' found at position 24.
//       '91119' found at position 33.
Dim pattern As String = "\b91*9*\b"
Dim input As String = "99 95 919 929 9119 9219 999 9919 91119"
For Each match As Match In Regex.Matches(input, pattern)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       '99' found at position 0.
'       '919' found at position 6.
'       '9119' found at position 14.
'       '999' found at position 24.
'       '91119' found at position 33.

Pola ekspresi reguler didefinisikan seperti yang ditunjukkan dalam tabel berikut:

Pola Deskripsi
\b Menentukan bahwa kecocokan harus dimulai pada batas kata.
91* Cocok 9 dengan karakter diikuti oleh nol atau lebih 1 .
9* Cocok dengan nol karakter atau lebih 9 .
\b Menentukan bahwa kecocokan harus berakhir pada batas kata.

Cocokkan Satu kali atau Lebih: +

Pembilang + cocok dengan elemen sebelumnya nol atau lebih kali. Ini setara dengan {1,}. + adalah pembilang rakus yang setara lembam adalah +?.

Misalnya, ekspresi \ban+\w*?\b reguler mencoba mencocokkan seluruh kata yang dimulai dengan huruf a diikuti oleh satu atau beberapa instans huruf n. Contoh berikut menggambarkan ekspresi reguler ini. Ekspresi reguler cocok dengan kata an, annual, announcement, dan antique, dan gagal mencocokkan autumn dan alldengan benar.

string pattern = @"\ban+\w*?\b";

string input = "Autumn is a great time for an annual announcement to all antique collectors.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);

// The example displays the following output:
//       'an' found at position 27.
//       'annual' found at position 30.
//       'announcement' found at position 37.
//       'antique' found at position 57.
Dim pattern As String = "\ban+\w*?\b"

Dim input As String = "Autumn is a great time for an annual announcement to all antique collectors."
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       'an' found at position 27.
'       'annual' found at position 30.
'       'announcement' found at position 37.
'       'antique' found at position 57.

Pola ekspresi reguler didefinisikan seperti yang ditunjukkan dalam tabel berikut:

Pola Deskripsi
\b Mulailah dari batas kata.
an+ Cocok dengan yang a diikuti oleh satu atau beberapa n karakter.
\w*? Mencocokkan karakter kata nol atau lebih kali tetapi sesekali mungkin.
\b Berakhir pada batas kata.

Cocokkan Zero atau One Time: ?

Pembilang ? cocok dengan elemen sebelumnya nol atau lebih kali. Ini setara dengan {0,1}. ? adalah pembilang rakus yang setara lembam adalah ??.

Misalnya, ekspresi \ban?\b reguler mencoba mencocokkan seluruh kata yang dimulai dengan huruf a diikuti dengan nol atau satu instans huruf n. Dengan kata lain, ia mencoba mencocokkan kata-kata a dan an. Contoh berikut mengilustrasikan ekspresi reguler ini:

string pattern = @"\ban?\b";
string input = "An amiable animal with a large snout and an animated nose.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);

// The example displays the following output:
//        'An' found at position 0.
//        'a' found at position 23.
//        'an' found at position 42.
Dim pattern As String = "\ban?\b"
Dim input As String = "An amiable animal with a large snout and an animated nose."
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       'An' found at position 0.
'       'a' found at position 23.
'       'an' found at position 42.

Pola ekspresi reguler didefinisikan seperti yang ditunjukkan dalam tabel berikut:

Pola Deskripsi
\b Mulailah dari batas kata.
an? Cocok dengan diikuti a oleh nol atau satu n karakter.
\b Berakhir pada batas kata.

Cocokkan Persis n Kali: {n}

Pembilang {n} cocok dengan elemen sebelumnya persis n kali, yang menandakan n sebagai setiap bilangan bulat. {n} adalah pembilang rakus yang setara lembam yakni {n}?.

Misalnya, ekspresi \b\d+\,\d{3}\b reguler mencoba mencocokkan batas kata diikuti oleh satu atau beberapa digit desimal diikuti oleh tiga digit desimal diikuti dengan batas kata. Contoh berikut mengilustrasikan ekspresi reguler ini:

string pattern = @"\b\d+\,\d{3}\b";
string input = "Sales totaled 103,524 million in January, " +
                      "106,971 million in February, but only " +
                      "943 million in March.";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);

//  The example displays the following output:
//        '103,524' found at position 14.
//        '106,971' found at position 45.
Dim pattern As String = "\b\d+\,\d{3}\b"
Dim input As String = "Sales totaled 103,524 million in January, " + _
                      "106,971 million in February, but only " + _
                      "943 million in March."
For Each match As Match In Regex.Matches(input, pattern)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       '103,524' found at position 14.
'       '106,971' found at position 45.

Pola ekspresi reguler didefinisikan seperti yang ditunjukkan dalam tabel berikut:

Pola Deskripsi
\b Mulailah dari batas kata.
\d+ Cocok dengan satu atau beberapa digit desimal.
\, Cocok dengan karakter koma.
\d{3} Cocok dengan tiga digit desimal.
\b Berakhir pada batas kata.

Cocokkan sedikitnya n Kali: {n,}

Pembilang {n,} cocok dengan elemen sebelumnya sedikitnya n kali, yang menandakan n sebagai setiap bilangan bulat. {n,} adalah pembilang rakus yang setara lembam yakni {n,}?.

Misalnya, ekspresi \b\d{2,}\b\D+ reguler mencoba mencocokkan batas kata diikuti oleh sedikitnya dua digit diikuti oleh batas kata dan karakter nondigit. Contoh berikut menggambarkan ekspresi reguler ini. Ekspresi reguler gagal mencocokkan frasa "7 days" karena hanya berisi satu digit desimal, tetapi berhasil mencocokkan frasa "10 weeks" dan "300 years".

string pattern = @"\b\d{2,}\b\D+";
string input = "7 days, 10 weeks, 300 years";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);

//  The example displays the following output:
//        '10 weeks, ' found at position 8.
//        '300 years' found at position 18.
Dim pattern As String = "\b\d{2,}\b\D+"
Dim input As String = "7 days, 10 weeks, 300 years"
For Each match As Match In Regex.Matches(input, pattern)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       '10 weeks, ' found at position 8.
'       '300 years' found at position 18.

Pola ekspresi reguler didefinisikan seperti yang ditunjukkan dalam tabel berikut:

Pola Deskripsi
\b Mulailah dari batas kata.
\d{2,} Mencocokkan setidaknya dua digit desimal.
\b Cocok dengan batas kata.
\D+ Mencocokkan setidaknya satu digit non-desimal.

Cocokkan Antara n dan m Times: {n,m}

Pembilang {n,m} cocok dengan elemen sebelumnya sedikitnya n kali, tetapi tidak lebih dari m kali, yang menandakan n dan m sebagai bilangan bulat. {n,m} adalah pembilang rakus setara lembam yakni {n,m}?.

Dalam contoh berikut, ekspresi (00\s){2,4} reguler mencoba mencocokkan antara dua dan empat kejadian dua digit nol diikuti oleh spasi. Bagian akhir dari string input mencakup pola ini lima kali daripada maksimum empat. Namun, hanya bagian awal dari substring ini (hingga ruang dan pasangan kelima nol) yang cocok dengan pola ekspresi reguler.

string pattern = @"(00\s){2,4}";
string input = "0x00 FF 00 00 18 17 FF 00 00 00 21 00 00 00 00 00";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);

//  The example displays the following output:
//        '00 00 ' found at position 8.
//        '00 00 00 ' found at position 23.
//        '00 00 00 00 ' found at position 35.
Dim pattern As String = "(00\s){2,4}"
Dim input As String = "0x00 FF 00 00 18 17 FF 00 00 00 21 00 00 00 00 00"
For Each match As Match In Regex.Matches(input, pattern)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       '00 00 ' found at position 8.
'       '00 00 00 ' found at position 23.
'       '00 00 00 00 ' found at position 35.

Cocokkan Nol atau Lebih Kali (Kecocokan Lembam): *?

Kuantifier *? cocok dengan elemen sebelumnya nol atau lebih kali tetapi sesekali mungkin. Ini adalah rekan malas dari kuantifier *serakah.

Dalam contoh berikut, ekspresi \b\w*?oo\w*?\b reguler cocok dengan semua kata yang berisi string oo.

 string pattern = @"\b\w*?oo\w*?\b";
 string input = "woof root root rob oof woo woe";
 foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);

 //  The example displays the following output:
//        'woof' found at position 0.
//        'root' found at position 5.
//        'root' found at position 10.
//        'oof' found at position 19.
//        'woo' found at position 23.
Dim pattern As String = "\b\w*?oo\w*?\b"
Dim input As String = "woof root root rob oof woo woe"
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       'woof' found at position 0.
'       'root' found at position 5.
'       'root' found at position 10.
'       'oof' found at position 19.
'       'woo' found at position 23.

Pola ekspresi reguler didefinisikan seperti yang ditunjukkan dalam tabel berikut:

Pola Deskripsi
\b Mulailah dari batas kata.
\w*? Mencocokkan nol atau lebih karakter kata tetapi sebanyak mungkin karakter.
oo Cocok dengan string oo.
\w*? Mencocokkan nol atau lebih karakter kata tetapi sebanyak mungkin karakter.
\b Akhiri dengan batas kata.

Cocokkan Satu Kali atau Lebih (Kecocokan Lembam): +?

Kuantifier +? cocok dengan elemen sebelumnya satu atau beberapa kali tetapi sesekali mungkin. Ini adalah rekan malas dari kuantifier +serakah.

Misalnya, ekspresi \b\w+?\b reguler cocok dengan satu atau beberapa karakter yang dipisahkan oleh batas kata. Contoh berikut mengilustrasikan ekspresi reguler ini:

string pattern = @"\b\w+?\b";
string input = "Aa Bb Cc Dd Ee Ff";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);

//  The example displays the following output:
//        'Aa' found at position 0.
//        'Bb' found at position 3.
//        'Cc' found at position 6.
//        'Dd' found at position 9.
//        'Ee' found at position 12.
//        'Ff' found at position 15.
Dim pattern As String = "\b\w+?\b"
Dim input As String = "Aa Bb Cc Dd Ee Ff"
For Each match As Match In Regex.Matches(input, pattern)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       'Aa' found at position 0.
'       'Bb' found at position 3.
'       'Cc' found at position 6.
'       'Dd' found at position 9.
'       'Ee' found at position 12.
'       'Ff' found at position 15.

Cocokkan Zero atau One Time (Kecocokan Lembam): ??

Kuantifier ?? cocok dengan elemen sebelumnya nol atau satu kali tetapi sesekali mungkin. Ini adalah rekan malas dari kuantifier ?serakah.

Misalnya, ekspresi ^\s*(System.)??Console.Write(Line)??\(?? reguler mencoba mencocokkan string Console.Write atau Console.WriteLine. String juga dapat menyertakan System. sebelum Console, dan dapat diikuti dengan tanda kurung pembuka. String harus berada di awal garis, meskipun dapat didahului oleh ruang putih. Contoh berikut mengilustrasikan ekspresi reguler ini:

string pattern = @"^\s*(System.)??Console.Write(Line)??\(??";
string input = "System.Console.WriteLine(\"Hello!\")\n" +
                      "Console.Write(\"Hello!\")\n" +
                      "Console.WriteLine(\"Hello!\")\n" +
                      "Console.ReadLine()\n" +
                      "   Console.WriteLine";
foreach (Match match in Regex.Matches(input, pattern,
                                      RegexOptions.IgnorePatternWhitespace |
                                      RegexOptions.IgnoreCase |
                                      RegexOptions.Multiline))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);

//  The example displays the following output:
//        'System.Console.Write' found at position 0.
//        'Console.Write' found at position 36.
//        'Console.Write' found at position 61.
//        '   Console.Write' found at position 110.
Dim pattern As String = "^\s*(System.)??Console.Write(Line)??\(??"
Dim input As String = "System.Console.WriteLine(""Hello!"")" + vbCrLf + _
                      "Console.Write(""Hello!"")" + vbCrLf + _
                      "Console.WriteLine(""Hello!"")" + vbCrLf + _
                      "Console.ReadLine()" + vbCrLf + _
                      "   Console.WriteLine"
For Each match As Match In Regex.Matches(input, pattern, _
                                         RegexOptions.IgnorePatternWhitespace Or RegexOptions.IgnoreCase Or RegexOptions.MultiLine)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       'System.Console.Write' found at position 0.
'       'Console.Write' found at position 36.
'       'Console.Write' found at position 61.
'       '   Console.Write' found at position 110.

Pola ekspresi reguler didefinisikan seperti yang ditunjukkan dalam tabel berikut:

Pola Deskripsi
^ Cocok dengan awal aliran input.
\s* Cocok dengan nol atau lebih karakter spasi kosong.
(System.)?? Cocok dengan nol atau satu kemunculan string System..
Console.Write Cocok dengan string Console.Write.
(Line)?? Cocok dengan nol atau satu kemunculan string Line.
\(?? Cocok dengan nol atau satu kemunculan tanda kurung pembuka.

Cocokkan Persis n Kali (Kecocokan Lembam): {n}?

Pembilang {n}? cocok dengan elemen sebelumnya persis n kali, yang menandakan n sebagai setiap bilangan bulat. Ini adalah rekan malas dari kuantifier {serakah n}.

Dalam contoh berikut, ekspresi \b(\w{3,}?\.){2}?\w{3,}?\b reguler digunakan untuk mengidentifikasi alamat situs web. Ekspresi cocok www.microsoft.com dan msdn.microsoft.com tetapi tidak cocok mywebsite atau mycompany.com.

string pattern = @"\b(\w{3,}?\.){2}?\w{3,}?\b";
string input = "www.microsoft.com msdn.microsoft.com mywebsite mycompany.com";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);

//  The example displays the following output:
//        'www.microsoft.com' found at position 0.
//        'msdn.microsoft.com' found at position 18.
Dim pattern As String = "\b(\w{3,}?\.){2}?\w{3,}?\b"
Dim input As String = "www.microsoft.com msdn.microsoft.com mywebsite mycompany.com"
For Each match As Match In Regex.Matches(input, pattern)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       'www.microsoft.com' found at position 0.
'       'msdn.microsoft.com' found at position 18.

Pola ekspresi reguler didefinisikan seperti yang ditunjukkan dalam tabel berikut:

Pola Deskripsi
\b Mulailah dari batas kata.
(\w{3,}?\.) Mencocokkan setidaknya tiga karakter kata tetapi seserang mungkin karakter, diikuti oleh karakter titik atau titik. Pola ini adalah grup penangkapan pertama.
(\w{3,}?\.){2}? Mencocokkan pola dalam grup pertama dua kali tetapi sesekali mungkin.
\b Akhiri pencocokan pada batas kata.

Cocokkan Sedikitnya n Kali (Kecocokan Lembam): {n,}?

Kuantifier {n,}? cocok dengan elemen sebelumnya setidaknya n kali, di mana n adalah bilangan bulat tetapi sesekali mungkin. Ini adalah rekan malas dari kuantifier {serakah n,}.

Lihat contoh untuk pembilang {n}? di bagian sebelumnya untuk ilustrasi. Ekspresi reguler dalam contoh tersebut { menggunakan pembilang n,} untuk mencocokkan string yang memiliki sedikitnya tiga karakter diikuti oleh titik.

Kecocokan Antara n dengan m Kali (Kecocokan Lembam): {n,m}?

Kuantifier {n,m}? cocok dengan elemen sebelumnya antara n dan m waktu, di mana n dan m adalah bilangan bulat tetapi sesegera mungkin. Ini adalah rekan malas dari kuantifier {serakah n,m}.

Dalam contoh berikut, ekspresi \b[A-Z](\w*?\s*?){1,10}[.!?] reguler cocok dengan kalimat yang berisi antara 1 dan 10 kata. Ini cocok dengan semua kalimat dalam string input kecuali satu kalimat yang berisi 18 kata.

string pattern = @"\b[A-Z](\w*?\s*?){1,10}[.!?]";
string input = "Hi. I am writing a short note. Its purpose is " +
                      "to test a regular expression that attempts to find " +
                      "sentences with ten or fewer words. Most sentences " +
                      "in this note are short.";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);

//  The example displays the following output:
//        'Hi.' found at position 0.
//        'I am writing a short note.' found at position 4.
//        'Most sentences in this note are short.' found at position 132.
Dim pattern As String = "\b[A-Z](\w*\s?){1,10}?[.!?]"
Dim input As String = "Hi. I am writing a short note. Its purpose is " + _
                      "to test a regular expression that attempts to find " + _
                      "sentences with ten or fewer words. Most sentences " + _
                      "in this note are short."
For Each match As Match In Regex.Matches(input, pattern)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       'Hi.' found at position 0.
'       'I am writing a short note.' found at position 4.
'       'Most sentences in this note are short.' found at position 132.

Pola ekspresi reguler didefinisikan seperti yang ditunjukkan dalam tabel berikut:

Pola Deskripsi
\b Mulailah dari batas kata.
[A-Z] Cocok dengan karakter huruf besar dari A ke Z.
(\w*?\s*?) Cocok dengan nol atau lebih karakter kata, diikuti oleh satu atau beberapa karakter spasi kosong tetapi sesekali mungkin. Pola ini adalah grup penangkapan pertama.
{1,10} Cocok dengan pola sebelumnya antara 1 dan 10 kali.
[.!?] Cocok dengan salah satu karakter .tanda baca , , !atau ?.

Pembilang rakus dan lembam

Beberapa kuantifier memiliki dua versi:

  • Versi rakus.

    Pembilang rakus mencoba mencocokkan elemen sebanyak mungkin.

  • Versi yang tidak rakus (atau lembam).

    Pembilang yang tidak rakus mencoba mencocokkan elemen sesedikit mungkin. Anda dapat mengubah kuantifier serakah menjadi kuantifier malas dengan menambahkan ?.

Pertimbangkan ekspresi reguler yang dimaksudkan untuk mengekstrak empat digit terakhir dari string angka, seperti nomor kartu kredit. Versi ekspresi reguler yang menggunakan * pembilang rakus adalah \b.*([0-9]{4})\b. Namun, jika string berisi dua angka, ekspresi reguler ini cocok dengan empat digit terakhir dari angka kedua saja, seperti yang ditunjukkan contoh berikut:

string greedyPattern = @"\b.*([0-9]{4})\b";
string input1 = "1112223333 3992991999";
foreach (Match match in Regex.Matches(input1, greedyPattern))
   Console.WriteLine("Account ending in ******{0}.", match.Groups[1].Value);

// The example displays the following output:
//       Account ending in ******1999.
Dim greedyPattern As String = "\b.*([0-9]{4})\b"
Dim input1 As String = "1112223333 3992991999"
For Each match As Match In Regex.Matches(input1, greedypattern)
    Console.WriteLine("Account ending in ******{0}.", match.Groups(1).Value)
Next
' The example displays the following output:
'       Account ending in ******1999.

Ekspresi reguler gagal mencocokkan angka pertama karena * pembilang mencoba mencocokkan elemen sebelumnya sebanyak mungkin di seluruh string, sehingga menemukan kecocokannya di akhir string.

Perilaku ini bukan yang diinginkan. Sebagai gantinya *? , Anda dapat menggunakan kuantifier malas untuk mengekstrak digit dari kedua angka, seperti yang ditunjukkan contoh berikut:

string lazyPattern = @"\b.*?([0-9]{4})\b";
string input2 = "1112223333 3992991999";
foreach (Match match in Regex.Matches(input2, lazyPattern))
   Console.WriteLine("Account ending in ******{0}.", match.Groups[1].Value);

// The example displays the following output:
//       Account ending in ******3333.
//       Account ending in ******1999.
Dim lazyPattern As String = "\b.*?([0-9]{4})\b"
Dim input2 As String = "1112223333 3992991999"
For Each match As Match In Regex.Matches(input2, lazypattern)
    Console.WriteLine("Account ending in ******{0}.", match.Groups(1).Value)
Next
' The example displays the following output:
'       Account ending in ******3333.
'       Account ending in ******1999.

Dalam kebanyakan kasus, ekspresi reguler dengan pembilang rakus dan lembam mengembalikan kecocokan yang sama. Mereka paling sering mengembalikan hasil yang berbeda ketika digunakan dengan metacharacter wildcard (.) yang cocok dengan karakter apa pun.

Pembilang dan Kecocokan Kosong

Pembilang *, +, dan {n,m} dan pasangan lembam mereka tidak pernah diulang setelah kecocokan kosong ketika jumlah minimum pengambilan telah ditemukan. Aturan ini mencegah pembilang memasuki pengulangan tak terbatas pada kecocokan subekspresi kosong ketika jumlah maksimum pengambilan grup yang mungkin tidak terbatas atau hampir tak terbatas.

Misalnya, kode berikut menunjukkan hasil panggilan ke Regex.Match metode dengan pola (a?)*ekspresi reguler , yang cocok dengan nol atau satu a karakter nol karakter atau lebih kali. Grup penangkapan tunggal menangkap masing-masing a dan String.Empty, tetapi tidak ada kecocokan kosong kedua karena kecocokan kosong pertama menyebabkan kuantifier berhenti mengulangi.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = "(a?)*";
      string input = "aaabbb";
      Match match = Regex.Match(input, pattern);
      Console.WriteLine("Match: '{0}' at index {1}",
                        match.Value, match.Index);
      if (match.Groups.Count > 1) {
         GroupCollection groups = match.Groups;
         for (int grpCtr = 1; grpCtr <= groups.Count - 1; grpCtr++) {
            Console.WriteLine("   Group {0}: '{1}' at index {2}",
                              grpCtr,
                              groups[grpCtr].Value,
                              groups[grpCtr].Index);
            int captureCtr = 0;
            foreach (Capture capture in groups[grpCtr].Captures) {
               captureCtr++;
               Console.WriteLine("      Capture {0}: '{1}' at index {2}",
                                 captureCtr, capture.Value, capture.Index);
            }
         }
      }
   }
}
// The example displays the following output:
//       Match: 'aaa' at index 0
//          Group 1: '' at index 3
//             Capture 1: 'a' at index 0
//             Capture 2: 'a' at index 1
//             Capture 3: 'a' at index 2
//             Capture 4: '' at index 3
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "(a?)*"
        Dim input As String = "aaabbb"
        Dim match As Match = Regex.Match(input, pattern)
        Console.WriteLine("Match: '{0}' at index {1}",
                          match.Value, match.Index)
        If match.Groups.Count > 1 Then
            Dim groups As GroupCollection = match.Groups
            For grpCtr As Integer = 1 To groups.Count - 1
                Console.WriteLine("   Group {0}: '{1}' at index {2}",
                                  grpCtr,
                                  groups(grpCtr).Value,
                                  groups(grpCtr).Index)
                Dim captureCtr As Integer = 0
                For Each capture As Capture In groups(grpCtr).Captures
                    captureCtr += 1
                    Console.WriteLine("      Capture {0}: '{1}' at index {2}",
                                      captureCtr, capture.Value, capture.Index)
                Next
            Next
        End If
    End Sub
End Module
' The example displays the following output:
'       Match: 'aaa' at index 0
'          Group 1: '' at index 3
'             Capture 1: 'a' at index 0
'             Capture 2: 'a' at index 1
'             Capture 3: 'a' at index 2
'             Capture 4: '' at index 3

Untuk melihat perbedaan praktis antara grup pengambilan yang menetapkan jumlah pengambilan dan maksimum dan yang menentukan jumlah pengambilan tetap, pertimbangkan pola ekspresi reguler (a\1|(?(1)\1)){0,2} dan (a\1|(?(1)\1)){2}. Kedua ekspresi reguler terdiri dari satu grup pengambilan, yang didefinisikan dalam tabel berikut:

Pola Deskripsi
(a\1 Salah satu kecocokan a bersama dengan nilai grup pertama yang diambil ...
|(?(1) ... atau menguji apakah grup pertama yang diambil telah ditentukan. Konstruksi (?(1) tidak menentukan grup pengambilan.
\1)) Jika grup pertama yang diambil ada, cocokkan nilainya. Jika grup tidak ada, grup akan cocok String.Emptydengan .

Ekspresi reguler pertama mencoba mencocokkan pola ini antara nol dan dua kali; yang kedua, persis dua kali. Karena pola pertama mencapai jumlah minimum pengambilannya dengan tangkapan String.Emptypertamanya , pola tersebut tidak pernah berulang untuk mencoba mencocokkan a\1. Kuantifier {0,2} hanya memungkinkan kecocokan kosong dalam iterasi terakhir. Sebaliknya, ekspresi reguler kedua cocok a karena mengevaluasi a\1 untuk kedua kalinya. Jumlah minimum iterasi, 2, memaksa mesin untuk mengulangi setelah kecocokan kosong.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern, input;

      pattern = @"(a\1|(?(1)\1)){0,2}";
      input = "aaabbb";

      Console.WriteLine("Regex pattern: {0}", pattern);
      Match match = Regex.Match(input, pattern);
      Console.WriteLine("Match: '{0}' at position {1}.",
                        match.Value, match.Index);
      if (match.Groups.Count > 1) {
         for (int groupCtr = 1; groupCtr <= match.Groups.Count - 1; groupCtr++)
         {
            Group group = match.Groups[groupCtr];
            Console.WriteLine("   Group: {0}: '{1}' at position {2}.",
                              groupCtr, group.Value, group.Index);
            int captureCtr = 0;
            foreach (Capture capture in group.Captures) {
               captureCtr++;
               Console.WriteLine("      Capture: {0}: '{1}' at position {2}.",
                                 captureCtr, capture.Value, capture.Index);
            }
         }
      }
      Console.WriteLine();

      pattern = @"(a\1|(?(1)\1)){2}";
      Console.WriteLine("Regex pattern: {0}", pattern);
      match = Regex.Match(input, pattern);
         Console.WriteLine("Matched '{0}' at position {1}.",
                           match.Value, match.Index);
      if (match.Groups.Count > 1) {
         for (int groupCtr = 1; groupCtr <= match.Groups.Count - 1; groupCtr++)
         {
            Group group = match.Groups[groupCtr];
            Console.WriteLine("   Group: {0}: '{1}' at position {2}.",
                              groupCtr, group.Value, group.Index);
            int captureCtr = 0;
            foreach (Capture capture in group.Captures) {
               captureCtr++;
               Console.WriteLine("      Capture: {0}: '{1}' at position {2}.",
                                 captureCtr, capture.Value, capture.Index);
            }
         }
      }
   }
}
// The example displays the following output:
//       Regex pattern: (a\1|(?(1)\1)){0,2}
//       Match: '' at position 0.
//          Group: 1: '' at position 0.
//             Capture: 1: '' at position 0.
//
//       Regex pattern: (a\1|(?(1)\1)){2}
//       Matched 'a' at position 0.
//          Group: 1: 'a' at position 0.
//             Capture: 1: '' at position 0.
//             Capture: 2: 'a' at position 0.
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern, input As String

        pattern = "(a\1|(?(1)\1)){0,2}"
        input = "aaabbb"

        Console.WriteLine("Regex pattern: {0}", pattern)
        Dim match As Match = Regex.Match(input, pattern)
        Console.WriteLine("Match: '{0}' at position {1}.",
                          match.Value, match.Index)
        If match.Groups.Count > 1 Then
            For groupCtr As Integer = 1 To match.Groups.Count - 1
                Dim group As Group = match.Groups(groupCtr)
                Console.WriteLine("   Group: {0}: '{1}' at position {2}.",
                                  groupCtr, group.Value, group.Index)
                Dim captureCtr As Integer = 0
                For Each capture As Capture In group.Captures
                    captureCtr += 1
                    Console.WriteLine("      Capture: {0}: '{1}' at position {2}.",
                                      captureCtr, capture.Value, capture.Index)
                Next
            Next
        End If
        Console.WriteLine()

        pattern = "(a\1|(?(1)\1)){2}"
        Console.WriteLine("Regex pattern: {0}", pattern)
        match = Regex.Match(input, pattern)
        Console.WriteLine("Matched '{0}' at position {1}.",
                          match.Value, match.Index)
        If match.Groups.Count > 1 Then
            For groupCtr As Integer = 1 To match.Groups.Count - 1
                Dim group As Group = match.Groups(groupCtr)
                Console.WriteLine("   Group: {0}: '{1}' at position {2}.",
                                  groupCtr, group.Value, group.Index)
                Dim captureCtr As Integer = 0
                For Each capture As Capture In group.Captures
                    captureCtr += 1
                    Console.WriteLine("      Capture: {0}: '{1}' at position {2}.",
                                      captureCtr, capture.Value, capture.Index)
                Next
            Next
        End If
    End Sub
End Module
' The example displays the following output:
'       Regex pattern: (a\1|(?(1)\1)){0,2}
'       Match: '' at position 0.
'          Group: 1: '' at position 0.
'             Capture: 1: '' at position 0.
'       
'       Regex pattern: (a\1|(?(1)\1)){2}
'       Matched 'a' at position 0.
'          Group: 1: 'a' at position 0.
'             Capture: 1: '' at position 0.
'             Capture: 2: 'a' at position 0.

Lihat juga