Pengelompokan konstruksi dalam ekspresi reguler

Konstruksi pengelompokan menggambarkan subekspresi dari regex dan menangkap substring dari string input. Anda dapat menggunakan konstruksi pengelompokan untuk melakukan hal berikut:

  • Cocokkan subekspresi yang diulang dalam string input.
  • Terapkan pembilang ke subekspresi yang memiliki beberapa elemen bahasa regex. Untuk informasi selengkapnya tentang pembilang, lihat Pembilang.
  • Sertakan subekspresi dalam string yang dikembalikan oleh Regex.Replace metode dan Match.Result .
  • Ambil subekspresi individual dari properti Match.Groups dan proses secara terpisah dari teks yang cocok secara keseluruhan.

Tabel berikut mencantumkan konstruksi pengelompokan yang didukung oleh mesin ekspresi reguler .NET dan menunjukkan apakah mereka menangkap atau tidak menangkap.

Pengelompokan konstruksi Menangkap atau tidak menangkap
Subekspresi yang cocok Menangkap
Subekspresi bernama yang cocok Menangkap
Definisi grup penyeimbang Menangkap
Grup yang tidak menangkap Tidak menangkap
Opsi grup Tidak menangkap
Pernyataan lookahead positif lebar-nol Tidak menangkap
Pernyataan lookahead negatif lebar-nol Tidak menangkap
Pernyataan lookbehind positif lebar-nol Tidak menangkap
Pernyataan lookbehind negatif lebar-nol Tidak menangkap
Grup atomik Tidak menangkap

Untuk informasi tentang grup dan model objek regex, lihat Konstruksi pengelompokan dan objek regex.

Subekspresi yang cocok

Konstruksi pengelompokan berikut menangkap subekspresi yang cocok:

(subekspresi)

Di sini, subekspresi adalah pola ekspresi reguler yang valid. Pengambilan yang menggunakan tanda kurung diberi nomor secara otomatis dari kiri ke kanan berdasarkan urutan tanda kurung pembuka dalam ekspresi reguler, mulai dari 1. Namun, grup pengambilan bernama selalu diurutkan terakhir, setelah grup penangkapan non-nama. Tangkapan yang bernomor 0 adalah teks yang cocok dengan seluruh pola ekspresi reguler.

Catatan

Secara default, elemen bahasa (subekspresi) menangkap subekspresi yang cocok. Tetapi jika RegexOptions parameter metode pencocokan pola ekspresi reguler menyertakan RegexOptions.ExplicitCapture bendera, atau jika n opsi diterapkan ke subekspresi ini (lihat Opsi grup nanti dalam artikel ini), subekspresi yang cocok tidak diambil.

Anda dapat mengakses grup yang ditangkap dengan empat cara:

  • Dengan menggunakan konstruksi referensi balik dalam regex. Subekspresi yang cocok direferensikan dalam regex yang sama dengan menggunakan sintaks \angka, di mana angka adalah angka ordinal dari subekspresi yang diambil.

  • Dengan menggunakan konstruksi referensi balik bernama dalam regex. Subekspresi yang cocok direferensikan dalam regex yang sama dengan menggunakan sintaks \k<nama>, di mana nama adalah nama grup penangkapan, atau \k<angka>, di mana angka adalah angka ordinal dari grup penangkapan. Grup penangkap memiliki nama default yang identik dengan angka ordinalnya. Untuk informasi selengkapnya, lihat Subekspresi bernama yang cocok nanti dalam topik ini.

  • Dengan menggunakan urutan penggantian $angka dalam panggilan metode Regex.Replace atau Match.Result, di mana angka adalah angka ordinal subekspresi yang diambil.

  • Secara terprogram, dengan menggunakan objek GroupCollection yang dikembalikan oleh properti Match.Groups. Anggota pada posisi nol dalam koleksi mewakili seluruh kecocokan regex. Setiap anggota berikutnya mewakili subekspresi yang cocok. Untuk informasi selengkapnya, lihat bagian Konstruksi Pengelompokan dan Objek Regex.

Contoh berikut menggambarkan regex yang mengidentifikasi kata-kata duplikat dalam teks. Dua grup penangkap pola regex mewakili dua instans kata yang diduplikasi. Instans kedua ditangkap untuk melaporkan posisi awalnya dalam string input.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"(\w+)\s(\1)\W";
      string input = "He said that that was the the correct answer.";
      foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
         Console.WriteLine("Duplicate '{0}' found at positions {1} and {2}.",
                           match.Groups[1].Value, match.Groups[1].Index, match.Groups[2].Index);
   }
}
// The example displays the following output:
//       Duplicate 'that' found at positions 8 and 13.
//       Duplicate 'the' found at positions 22 and 26.
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "(\w+)\s(\1)\W"
        Dim input As String = "He said that that was the the correct answer."
        For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
            Console.WriteLine("Duplicate '{0}' found at positions {1} and {2}.", _
                              match.Groups(1).Value, match.Groups(1).Index, match.Groups(2).Index)
        Next
    End Sub
End Module
' The example displays the following output:
'       Duplicate 'that' found at positions 8 and 13.
'       Duplicate 'the' found at positions 22 and 26.

Pola regex-nya adalah sebagai berikut:

(\w+)\s(\1)\W

Tabel berikut menunjukkan bagaimana pola regex ditafsirkan.

Pola Deskripsi
(\w+) Mencocokkan satu atau beberapa karakter kata. Ini adalah grup penangkapan pertama.
\s Cocokkan karakter spasi kosong.
(\1) Cocokkan string dalam grup pertama yang ditangkap. Ini adalah grup pengambilan kedua. Contoh menetapkannya ke grup yang diambil sehingga posisi awal kata duplikat dapat diambil dari properti Match.Index.
\W Cocokkan karakter non-kata, termasuk whitespace dan tanda baca. Ini mencegah pola regex dari pencocokan kata yang dimulai dengan kata dari grup pertama yang ditangkap.

Subekspresi bernama yang cocok

Konstruksi pengelompokan berikut menangkap subekspresi yang cocok dan memungkinkan Anda mengaksesnya menurut nama atau nomor:

(?<name>subexpression)

atau:

(?'name'subexpression)

Di sini, nama adalah nama grup yang valid, dan subekspresi adalah pola ekspresi reguler yang valid. nama tidak boleh berisi karakter tanda baca apa pun dan tidak dapat dimulai dengan angka.

Catatan

Tetapi jika parameter RegexOptions dari metode pencocokan pola regex menyertakan bendera RegexOptions.ExplicitCapture, atau jika opsi n diterapkan ke subekspresi ini (lihat Opsi grup nanti dalam topik ini), satu-satunya cara untuk menangkap subekspresi adalah dengan secara eksplisit memberi nama grup penangkapan.

Anda dapat mengakses grup bernama yang diambil dengan cara berikut:

  • Dengan menggunakan konstruksi referensi balik bernama dalam regex. Subekspresi yang cocok direferensikan dalam regex yang sama dengan menggunakan sintaks \k<nama>, di mana nama adalah nama dari subekspresi yang diambil.

  • Dengan menggunakan konstruksi referensi balik dalam regex. Subekspresi yang cocok direferensikan dalam regex yang sama dengan menggunakan sintaks \angka, di mana angka adalah angka ordinal dari subekspresi yang diambil. Subekspresi bernama yang cocok diberi nomor berturut-turut dari kiri ke kanan setelah subekspresi yang cocok.

  • Dengan menggunakan urutan penggantian ${nama} dalam panggilan metode Regex.Replace atau Match.Result, di mana nama adalah nama subekspresi yang ditangkap.

  • Dengan menggunakan urutan penggantian $angka dalam panggilan metode Regex.Replace atau Match.Result, di mana angka adalah angka ordinal subekspresi yang diambil.

  • Secara terprogram, dengan menggunakan objek GroupCollection yang dikembalikan oleh properti Match.Groups. Anggota pada posisi nol dalam koleksi mewakili seluruh kecocokan regex. Setiap anggota berikutnya mewakili subekspresi yang cocok. Grup bernama yang ditangkap disimpan dalam koleksi setelah grup yang ditangkap bernomor.

  • Secara terprogram, dengan memberikan nama subekspresi ke pengindeks objek GroupCollection (dalam C#) atau ke propertinya Item[] (dalam Visual Basic).

Pola regex sederhana menggambarkan bagaimana kelompok bernomor (tidak bernama) dan bernama dapat direferensikan baik secara terprogram atau dengan menggunakan sintaks bahasa regex. Regex ((?<One>abc)\d+)?(?<Two>xyz)(.*) menghasilkan grup pengambilan berikut menurut angka dan nama. Kelompok penangkap pertama (angka 0) selalu mengacu pada seluruh pola. (Grup bernama selalu diurutkan terakhir.)

Angka Nama Pola
0 0 (nama default) ((?<One>abc)\d+)?(?<Two>xyz)(.*)
1 1 (nama default) ((?<One>abc)\d+)
2 2 (nama default) (.*)
3 Satu (?<One>abc)
4 Dua (?<Two>xyz)

Contoh berikut menggambarkan regex yang mengidentifikasi kata-kata duplikat dan kata yang segera mengikuti setiap kata yang diduplikasi. Pola ekspresi reguler mendefinisikan dua subekspresi bernama: duplicateWord, yang mewakili kata duplikat, dan nextWord, yang mewakili kata yang mengikuti kata duplikat.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)";
      string input = "He said that that was the the correct answer.";
      foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
         Console.WriteLine("A duplicate '{0}' at position {1} is followed by '{2}'.",
                           match.Groups["duplicateWord"].Value, match.Groups["duplicateWord"].Index,
                           match.Groups["nextWord"].Value);
   }
}
// The example displays the following output:
//       A duplicate 'that' at position 8 is followed by 'was'.
//       A duplicate 'the' at position 22 is followed by 'correct'.
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)"
        Dim input As String = "He said that that was the the correct answer."
        Console.WriteLine(Regex.Matches(input, pattern, RegexOptions.IgnoreCase).Count)
        For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
            Console.WriteLine("A duplicate '{0}' at position {1} is followed by '{2}'.", _
                              match.Groups("duplicateWord").Value, match.Groups("duplicateWord").Index, _
                              match.Groups("nextWord").Value)
        Next
    End Sub
End Module
' The example displays the following output:
'    A duplicate 'that' at position 8 is followed by 'was'.
'    A duplicate 'the' at position 22 is followed by 'correct'.

Pola regex adalah sebagai berikut:

(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)

Tabel berikut menunjukkan bagaimana regex ditafsirkan.

Pola Deskripsi
(?<duplicateWord>\w+) Mencocokkan satu atau beberapa karakter kata. Beri nama grup penangkap ini duplicateWord.
\s Cocokkan karakter spasi kosong.
\k<duplicateWord> Cocokkan string dari grup yang diambil yang diberi nama duplicateWord.
\W Cocokkan karakter non-kata, termasuk whitespace dan tanda baca. Ini mencegah pola regex dari pencocokan kata yang dimulai dengan kata dari grup pertama yang ditangkap.
(?<nextWord>\w+) Mencocokkan satu atau beberapa karakter kata. Beri nama grup penangkap ini nextWord.

Nama grup dapat diulang dalam ekspresi reguler. Misalnya, dimungkinkan bagi lebih dari satu grup untuk diberi nama digit, seperti yang diilustrasikan contoh berikut. Dalam kasus nama duplikat, nilai objek Group ditentukan oleh pengambilan terakhir yang berhasil dalam string input. Selain itu, CaptureCollection diisi dengan informasi tentang setiap tangkapan sama seperti jika nama grup tidak diduplikasi.

Dalam contoh berikut, regex\D+(?<digit>\d+)\D+(?<digit>\d+)? menyertakan dua kemunculan grup bernama digit. Grup bernama digit pertama menangkap satu atau beberapa karakter digit. Grup bernama digit kedua menangkap nol atau satu kemunculan dari satu atau beberapa karakter digit. Seperti yang ditunjukkan oleh output dari contoh, jika grup penangkapan kedua berhasil mencocokkan teks, nilai teks tersebut menentukan nilai objek Group. Jika grup penangkapan kedua tidak cocok dengan string input, nilai kecocokan terakhir yang berhasil menentukan nilai Group objek.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      String pattern = @"\D+(?<digit>\d+)\D+(?<digit>\d+)?";
      String[] inputs = { "abc123def456", "abc123def" };
      foreach (var input in inputs) {
         Match m = Regex.Match(input, pattern);
         if (m.Success) {
            Console.WriteLine("Match: {0}", m.Value);
            for (int grpCtr = 1; grpCtr < m.Groups.Count; grpCtr++) {
               Group grp = m.Groups[grpCtr];
               Console.WriteLine("Group {0}: {1}", grpCtr, grp.Value);
               for (int capCtr = 0; capCtr < grp.Captures.Count; capCtr++)
                  Console.WriteLine("   Capture {0}: {1}", capCtr,
                                    grp.Captures[capCtr].Value);
            }
         }
         else {
            Console.WriteLine("The match failed.");
         }
         Console.WriteLine();
      }
   }
}
// The example displays the following output:
//       Match: abc123def456
//       Group 1: 456
//          Capture 0: 123
//          Capture 1: 456
//
//       Match: abc123def
//       Group 1: 123
//          Capture 0: 123
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\D+(?<digit>\d+)\D+(?<digit>\d+)?"
        Dim inputs() As String = {"abc123def456", "abc123def"}
        For Each input As String In inputs
            Dim m As Match = Regex.Match(input, pattern)
            If m.Success Then
                Console.WriteLine("Match: {0}", m.Value)
                For grpCtr As Integer = 1 to m.Groups.Count - 1
                    Dim grp As Group = m.Groups(grpCtr)
                    Console.WriteLine("Group {0}: {1}", grpCtr, grp.Value)
                    For capCtr As Integer = 0 To grp.Captures.Count - 1
                        Console.WriteLine("   Capture {0}: {1}", capCtr,
                                          grp.Captures(capCtr).Value)
                    Next
                Next
            Else
                Console.WriteLine("The match failed.")
            End If
            Console.WriteLine()
        Next
    End Sub
End Module
' The example displays the following output:
'       Match: abc123def456
'       Group 1: 456
'          Capture 0: 123
'          Capture 1: 456
'
'       Match: abc123def
'       Group 1: 123
'          Capture 0: 123

Tabel berikut menunjukkan bagaimana regex ditafsirkan.

Pola Deskripsi
\D+ Cocokkan satu atau beberapa karakter digit non-desimal.
(?<digit>\d+) Cocokkan satu atau beberapa karakter digit desimal. Tetapkan kecocokan ke grup bernama digit.
\D+ Cocokkan satu atau beberapa karakter digit non-desimal.
(?<digit>\d+)? Cocokkan nol atau satu kejadian dari satu atau beberapa karakter digit desimal. Tetapkan kecocokan ke grup bernama digit.

Definisi grup penyeimbang

Definisi grup penyeimbangan menghapus definisi grup dan penyimpanan yang ditentukan sebelumnya, dalam grup saat ini, interval antara grup yang ditentukan sebelumnya dan grup saat ini. Konstruksi pengelompokan ini berformat berikut:

(?<name1-name2>subexpression)

atau:

(?'name1-name2' subexpression)

Di sini, name1 adalah grup saat ini (opsional), name2 adalah grup yang ditentukan sebelumnya, dan subekspresi adalah pola ekspresi reguler yang valid. Definisi grup penyeimbangan menghapus definisi name2 dan menyimpan interval antara name2 dan name1 di name1. Jika tidak ada grup name2 yang ditentukan, pencocokan akan dibalik. Karena menghapus definisi terakhir name2 mengungkapkan definisi name2 sebelumnya, konstruksi ini memungkinkan Anda menggunakan tumpukan tangkapan untuk name2 grup sebagai penghitung untuk melacak konstruksi bersarang seperti tanda kurung atau tanda kurung buka dan tutup.

Definisi grup penyeimbangan menggunakan name2 sebagai tumpukan. Karakter awal dari setiap konstruksi bersarang ditempatkan dalam grup dan dalam koleksi Group.Captures. Saat karakter penutup dicocokkan, karakter pembuka yang sesuai dihapus dari grup, dan koleksi Captures dikurangi satu. Setelah karakter pembuka dan penutup dari semua konstruksi bersarang telah dicocokkan, name2 kosong.

Catatan

Setelah Anda memodifikasi regex dalam contoh berikut untuk menggunakan karakter pembukaan dan penutupan yang sesuai dari konstruksi bersarang, Anda dapat menggunakannya untuk menangani sebagian besar konstruksi bersarang, seperti ekspresi matematika atau baris kode program yang menyertakan beberapa panggilan metode bersarang.

Contoh berikut menggunakan definisi grup penyeimbangan untuk mencocokkan tanda kurung sudut kiri dan kanan (<>) dalam string input. Contoh berikut mendefinisikan dua grup bernama, Open dan Close, yang digunakan seperti tumpukan untuk melacak pasangan tanda kurung sudut yang cocok. Setiap tanda kurung sudut kiri yang ditangkap didorong ke dalam kumpulan tangkapan grup Open, dan setiap tanda kurung sudut kanan yang ditangkap didorong ke dalam kumpulan tangkapan grup Close. Definisi kelompok penyeimbang memastikan bahwa ada tanda kurung sudut kanan yang cocok untuk setiap tanda kurung sudut kiri. Jika tidak ada, subpola akhir, (?(Open)(?!)), dievaluasi hanya jika grup Open tidak kosong (dan, oleh karena itu, jika semua konstruksi bersarang belum ditutup). Jika subpola akhir dievaluasi, kecocokan gagal, karena subpola (?!) adalah pernyataan lookahead negatif lebar nol yang selalu gagal.

using System;
using System.Text.RegularExpressions;

class Example
{
   public static void Main()
   {
      string pattern = "^[^<>]*" +
                       "(" +
                       "((?'Open'<)[^<>]*)+" +
                       "((?'Close-Open'>)[^<>]*)+" +
                       ")*" +
                       "(?(Open)(?!))$";
      string input = "<abc><mno<xyz>>";

      Match m = Regex.Match(input, pattern);
      if (m.Success == true)
      {
         Console.WriteLine("Input: \"{0}\" \nMatch: \"{1}\"", input, m);
         int grpCtr = 0;
         foreach (Group grp in m.Groups)
         {
            Console.WriteLine("   Group {0}: {1}", grpCtr, grp.Value);
            grpCtr++;
            int capCtr = 0;
            foreach (Capture cap in grp.Captures)
            {
                Console.WriteLine("      Capture {0}: {1}", capCtr, cap.Value);
                capCtr++;
            }
          }
      }
      else
      {
         Console.WriteLine("Match failed.");
      }
    }
}
// The example displays the following output:
//    Input: "<abc><mno<xyz>>"
//    Match: "<abc><mno<xyz>>"
//       Group 0: <abc><mno<xyz>>
//          Capture 0: <abc><mno<xyz>>
//       Group 1: <mno<xyz>>
//          Capture 0: <abc>
//          Capture 1: <mno<xyz>>
//       Group 2: <xyz
//          Capture 0: <abc
//          Capture 1: <mno
//          Capture 2: <xyz
//       Group 3: >
//          Capture 0: >
//          Capture 1: >
//          Capture 2: >
//       Group 4:
//       Group 5: mno<xyz>
//          Capture 0: abc
//          Capture 1: xyz
//          Capture 2: mno<xyz>
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "^[^<>]*" & _
                                "(" + "((?'Open'<)[^<>]*)+" & _
                                "((?'Close-Open'>)[^<>]*)+" + ")*" & _
                                "(?(Open)(?!))$"
        Dim input As String = "<abc><mno<xyz>>"
        Dim rgx AS New Regex(pattern) '
        Dim m As Match = Regex.Match(input, pattern)
        If m.Success Then
            Console.WriteLine("Input: ""{0}"" " & vbCrLf & "Match: ""{1}""", _
                               input, m)
            Dim grpCtr As Integer = 0
            For Each grp As Group In m.Groups
                Console.WriteLine("   Group {0}: {1}", grpCtr, grp.Value)
                grpCtr += 1
                Dim capCtr As Integer = 0
                For Each cap As Capture In grp.Captures
                    Console.WriteLine("      Capture {0}: {1}", capCtr, cap.Value)
                    capCtr += 1
                Next
            Next
        Else
            Console.WriteLine("Match failed.")
        End If
    End Sub
End Module
' The example displays the following output:
'       Input: "<abc><mno<xyz>>"
'       Match: "<abc><mno<xyz>>"
'          Group 0: <abc><mno<xyz>>
'             Capture 0: <abc><mno<xyz>>
'          Group 1: <mno<xyz>>
'             Capture 0: <abc>
'             Capture 1: <mno<xyz>>
'          Group 2: <xyz
'             Capture 0: <abc
'             Capture 1: <mno
'             Capture 2: <xyz
'          Group 3: >
'             Capture 0: >
'             Capture 1: >
'             Capture 2: >
'          Group 4:
'          Group 5: mno<xyz>
'             Capture 0: abc
'             Capture 1: xyz
'             Capture 2: mno<xyz>

Pola regex adalah:

^[^<>]*(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*(?(Open)(?!))$

Regex ditafsirkan sebagai berikut:

Pola Deskripsi
^ Mulailah dari awal string.
[^<>]* Cocokkan nol atau lebih karakter yang bukan tanda kurung sudut kiri atau kanan.
(?'Open'<) Cocokkan tanda kurung sudut kiri dan tetapkan ke grup bernama Open.
[^<>]* Cocokkan nol atau lebih karakter yang bukan tanda kurung sudut kiri atau kanan.
((?'Open'<)[^<>]*)+ Cocokkan satu atau beberapa kejadian tanda kurung sudut kiri diikuti dengan nol atau lebih karakter yang bukan tanda kurung sudut kiri atau kanan. Ini adalah grup pengambilan kedua.
(?'Close-Open'>) Cocokkan tanda kurung sudut kanan, tetapkan substring antara grup Open dan grup saat ini ke grup Close, dan hapus definisi grup Open.
[^<>]* Cocokkan nol atau lebih kejadian karakter apa pun yang bukan tanda kurung sudut kiri atau kanan.
((?'Close-Open'>)[^<>]*)+ Cocokkan satu atau lebih kejadian tanda kurung sudut kanan, diikuti dengan nol atau lebih kejadian karakter apa pun yang bukan tanda kurung sudut kiri atau kanan. Saat mencocokkan tanda kurung sudut kanan, tetapkan substring antara grup Open dan grup saat ini ke grup Close, dan hapus definisi grup Open. Ini adalah grup pengambilan ketiga.
(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)* Cocokkan nol atau lebih kejadian dari pola berikut: satu atau lebih kejadian tanda kurung sudut kiri, diikuti oleh nol atau lebih karakter tanda kurung non-sudut, diikuti oleh satu atau lebih kejadian tanda kurung sudut kanan, diikuti oleh nol atau lebih kejadian tanda kurung non-sudut. Saat mencocokkan tanda kurung sudut kanan, hapus definisi grup Open, dan tetapkan substring antara grup Open dan grup saat ini ke grup Close. Ini adalah grup penangkapan pertama.
(?(Open)(?!)) Jika grup Open ada, abaikan kecocokan jika string kosong dapat dicocokkan, tetapi jangan lanjutkan posisi mesin regex dalam string. Ini adalah pernyataan lookahead negatif lebar nol. Karena string kosong selalu hadir secara implisit dalam string input, kecocokan ini selalu gagal. Kegagalan pencocokan ini menunjukkan bahwa tanda kurung sudut tidak seimbang.
$ Cocokkan akhir string input.

Subekspresi akhir, (?(Open)(?!)), mengindikasikan apakah konstruksi bersarang dalam string input diseimbangkan dengan benar (misalnya, apakah setiap tanda kurung sudut kiri dicocokkan dengan tanda kurung sudut kanan). Ini menggunakan pencocokan kondisional berdasarkan grup yang diambil yang valid; untuk informasi selengkapnya, lihat Konstruksi Pergantian. Jika grup Open ditentukan, mesin regex mencoba mencocokkan subekspresi (?!) dalam string input. Grup Open harus didefinisikan hanya jika konstruksi bersarang tidak seimbang. Oleh karena itu, pola yang akan dicocokkan dalam string input harus menjadi salah satu yang selalu menyebabkan pencocokan gagal. Dalam hal ini, (?!) adalah pernyataan lookahead negatif lebar nol yang selalu gagal, karena string kosong selalu secara implisit ada pada posisi berikutnya dalam string input.

Dalam contoh, mesin regex mengevaluasi string input "<abc><mno<xyz>>" seperti yang ditunjukkan pada tabel berikut.

Langkah Pola Hasil
1 ^ Memulai pencocokan di awal string input
2 [^<>]* Mencari karakter tanda kurung non-sudut sebelum tanda kurung sudut kiri;tidak menemukan kecocokan.
3 (((?'Open'<) Mencocokkan dengan tanda kurung sudut kiri di "<abc>" dan menetapkannya ke grup Open.
4 [^<>]* Mencocokkan dengan "abc".
5 )+ "<abc" adalah nilai dari grup kedua yang ditangkap.

Karakter berikutnya dalam string input bukan tanda kurung sudut kiri, sehingga mesin regex tidak mengulang kembali ke subpola (?'Open'<)[^<>]*).
6 ((?'Close-Open'>) Mencocokkan dengan tanda kurung sudut kanan di "<abc>", menetapkan "abc", yang merupakan substring antara grup Open dan tanda kurung sudut kanan, ke grup Close, dan menghapus nilai saat ini ("<") dari grup Open, membiarkannya kosong.
7 [^<>]* Mencari karakter tanda kurung non-sudut setelah tanda kurung sudut kanan; tidak menemukan kecocokan.
8 )+ Nilai grup ketiga yang ditangkap adalah ">".

Karakter berikutnya dalam string input bukan tanda kurung sudut kanan, sehingga mesin regex tidak mengulang kembali ke subpola ((?'Close-Open'>)[^<>]*).
9 )* Nilai grup pertama yang ditangkap adalah "<abc>".

Karakter berikutnya dalam string input adalah tanda kurung sudut kiri, sehingga mesin regex mengulang kembali ke subpola (((?'Open'<).
10 (((?'Open'<) Mencocokkan dengan tanda kurung sudut kiri di "<mno" dan menetapkannya ke grup Open. Koleksi Group.Captures sekarang memiliki nilai tunggal, "<".
11 [^<>]* Mencocokkan “mno”.
12 )+ "<mno" adalah nilai dari grup kedua yang ditangkap.

Karakter berikutnya dalam string input adalah tanda kurung sudut kiri, sehingga mesin regex mengulang kembali ke subpola (?'Open'<)[^<>]*).
13 (((?'Open'<) Mencocokkan dengan tanda kurung sudut kiri di "<xyz>" dan menetapkannya ke grup Open. Koleksi Group.Captures dari grup Open sekarang mencakup dua tangkapan: tanda kurung sudut kiri dari "<mno", dan tanda kurung sudut kiri dari "<xyz>".
14 [^<>]* Mencocokkan "xyz".
15 )+ "<xyz" adalah nilai dari grup kedua yang ditangkap.

Karakter berikutnya dalam string input bukan tanda kurung sudut kiri, sehingga mesin regex tidak mengulang kembali ke subpola (?'Open'<)[^<>]*).
16 ((?'Close-Open'>) Mencocokkan dengan tanda kurung sudut kanan di "<xyz>". "xyz", menetapkan substring antara grup Open dan tanda kurung sudut kanan ke grup Close, dan menghapus nilai grup Open saat ini. Nilai pengambilan sebelumnya (tanda kurung sudut kiri di "<mno") menjadi nilai grup Open saat ini. Koleksi Captures dari grup Open sekarang mencakup satu tangkapan, tanda kurung sudut kiri dari "<xyz>".
17 [^<>]* Mencari karakter tanda kurung non-sudut; tidak menemukan kecocokan.
18 )+ Nilai grup ketiga yang ditangkap adalah ">".

Karakter berikutnya dalam string input adalah tanda kurung sudut kanan, sehingga mesin regex mengulang kembali ke subpola ((?'Close-Open'>)[^<>]*).
19 ((?'Close-Open'>) Mencocokkan dengan tanda kurung sudut kanan akhir di "xyz>>", menetapkan "mno<xyz>” (substring antara grup Open dan tanda kurung sudut kanan) ke grup Close, dan menghapus nilai saat ini dari grup Open. Grup Open sekarang kosong.
20 [^<>]* Mencari karakter tanda kurung non-sudut; tidak menemukan kecocokan.
21 )+ Nilai grup ketiga yang ditangkap adalah ">".

Karakter berikutnya dalam string input bukan tanda kurung sudut kanan, sehingga mesin regex tidak mengulang kembali ke subpola ((?'Close-Open'>)[^<>]*).
22 )* Nilai grup pertama yang ditangkap adalah "<mno<xyz>>".

Karakter berikutnya dalam string input bukan tanda kurung sudut kiri, sehingga mesin regex tidak mengulang kembali ke subpola (((?'Open'<).
23 (?(Open)(?!)) Grup Open tidak ditentukan, jadi tidak ada kecocokan yang dicoba.
24 $ Cocok dengan akhir string input.

Grup yang tidak menangkap

Konstruksi pengelompokan berikut tidak menangkap substring yang cocok dengan subekspresi:

(?:subexpression)

Di sini, subekspresi adalah pola ekspresi reguler yang valid. Konstruksi kelompok yang tidak menangkap biasanya digunakan ketika pembilang diterapkan pada suatu grup, tetapi substring yang ditangkap oleh grup tidak menarik.

Catatan

Jika regex menyertakan konstruksi pengelompokan bersarang, konstruksi kelompok luar yang tidak menangkap tidak berlaku untuk konstruksi grup bersarang bagian dalam.

Contoh berikut menggambarkan regex yang mencakup grup yang tidak menangkap. Perhatikan bahwa output tidak termasuk grup yang ditangkap.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"(?:\b(?:\w+)\W*)+\.";
      string input = "This is a short sentence.";
      Match match = Regex.Match(input, pattern);
      Console.WriteLine("Match: {0}", match.Value);
      for (int ctr = 1; ctr < match.Groups.Count; ctr++)
         Console.WriteLine("   Group {0}: {1}", ctr, match.Groups[ctr].Value);
   }
}
// The example displays the following output:
//       Match: This is a short sentence.
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "(?:\b(?:\w+)\W*)+\."
        Dim input As String = "This is a short sentence."
        Dim match As Match = Regex.Match(input, pattern)
        Console.WriteLine("Match: {0}", match.Value)
        For ctr As Integer = 1 To match.Groups.Count - 1
            Console.WriteLine("   Group {0}: {1}", ctr, match.Groups(ctr).Value)
        Next
    End Sub
End Module
' The example displays the following output:
'       Match: This is a short sentence.

Regex (?:\b(?:\w+)\W*)+\. cocok dengan kalimat yang dihentikan oleh titik. Karena regex berfokus pada kalimat dan bukan pada kata-kata individu, konstruksi pengelompokan digunakan secara eksklusif sebagai pembilang. Pola regex ditafsirkan seperti yang ditunjukkan pada tabel berikut.

Pola Deskripsi
\b Memulai pencocokan dalam batas kata.
(?:\w+) Mencocokkan satu atau beberapa karakter kata. Jangan tetapkan teks yang cocok ke grup yang diambil.
\W* Cocokkan nol atau lebih karakter non-kata.
(?:\b(?:\w+)\W*)+ Cocokkan pola satu atau lebih karakter kata mulai dari batas kata, diikuti oleh nol atau lebih karakter non-kata, satu kali atau lebih. Jangan tetapkan teks yang cocok ke grup yang diambil.
\. Cocokkan tanda titik.

Opsi grup

Konstruksi pengelompokan berikut berlaku atau menonaktifkan opsi yang ditentukan dalam subekspresi:

(?imnsx-imnsx:subekspresi)

Di sini, subekspresi adalah pola ekspresi reguler yang valid. Misalnya, (?i-s:) mengaktifkan ketidakpekaan huruf besar/kecil dan menonaktifkan mode baris tunggal. Untuk informasi selengkapnya tentang opsi sebaris yang bisa Anda tentukan, lihat Opsi Regex.

Catatan

Anda dapat menentukan opsi yang berlaku untuk seluruh regex daripada subekspresi dengan menggunakan konstruktor kelas System.Text.RegularExpressions.Regex atau metode statik. Anda juga dapat menentukan opsi sebaris yang berlaku setelah titik tertentu dalam regex dengan menggunakan konstruksi bahasa (?imnsx-imnsx).

Konstruksi opsi grup bukanlah grup penangkap. Artinya, meskipun sebagian string yang ditangkap oleh subekspresi disertakan dalam kecocokan, itu tidak termasuk dalam grup yang ditangkap atau digunakan untuk mengisi objek GroupCollection.

Misalnya, regex \b(?ix: d \w+)\s dalam contoh berikut menggunakan opsi sebaris dalam konstruksi pengelompokan untuk mengaktifkan pencocokan yang tidak peka huruf besar/kecil dan mengabaikan whitespace pola dalam mengidentifikasi semua kata yang dimulai dengan huruf "d". Regex didefinisikan seperti yang ditunjukkan pada tabel berikut.

Pola Deskripsi
\b Memulai pencocokan dalam batas kata.
(?ix: d \w+) Menggunakan pencocokan yang tidak peka huruf besar/kecil dan mengabaikan whitespace dalam pola ini, cocok dengan "d" diikuti oleh satu atau beberapa karakter kata.
\s Cocokkan karakter spasi kosong.
string pattern = @"\b(?ix: d \w+)\s";
string input = "Dogs are decidedly good pets.";

foreach (Match match in Regex.Matches(input, pattern))
    Console.WriteLine("'{0}// found at index {1}.", match.Value, match.Index);
// The example displays the following output:
//    'Dogs // found at index 0.
//    'decidedly // found at index 9.
Dim pattern As String = "\b(?ix: d \w+)\s"
Dim input As String = "Dogs are decidedly good pets."

For Each match As Match In Regex.Matches(input, pattern)
    Console.WriteLine("'{0}' found at index {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'    'Dogs ' found at index 0.
'    'decidedly ' found at index 9.      

Pernyataan lookahead positif lebar-nol

Konstruksi pengelompokan berikut mendefinisikan pernyataan lookahead positif lebar nol:

(?=subekspresi)

Di sini, subekspresi adalah pola ekspresi reguler apa pun. Agar kecocokan berhasil, string input harus cocok dengan pola regex dalam subekspresi, meskipun substring yang cocok tidak disertakan dalam hasil pencocokan. Pernyataan lookahead positif lebar nol tidak mundur.

Biasanya, pernyataan lookahead positif lebar nol ditemukan di akhir pola regex. Ini mendefinisikan substring yang harus ditemukan di akhir string agar kecocokan terjadi tetapi itu tidak boleh dimasukkan dalam kecocokannya. Hal ini juga berguna untuk mencegah backtracking yang berlebihan. Anda dapat menggunakan pernyataan lookahead positif lebar nol untuk memastikan bahwa grup yang ditangkap tertentu dimulai dengan teks yang cocok dengan subset dari pola yang ditentukan untuk grup yang ditangkap tersebut. Misalnya, jika grup penangkap cocok dengan karakter kata berturut-turut, Anda dapat menggunakan pernyataan lookahead positif lebar nol untuk mengharuskan karakter pertama menjadi karakter huruf besar alfabetik.

Contoh berikut menggunakan pernyataan lookahead positif lebar nol untuk mencocokkan kata yang mendahului kata kerja "adalah" dalam string input.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b\w+(?=\sis\b)";
      string[] inputs = { "The dog is a Malamute.",
                          "The island has beautiful birds.",
                          "The pitch missed home plate.",
                          "Sunday is a weekend day." };

      foreach (string input in inputs)
      {
         Match match = Regex.Match(input, pattern);
         if (match.Success)
            Console.WriteLine("'{0}' precedes 'is'.", match.Value);
         else
            Console.WriteLine("'{0}' does not match the pattern.", input);
      }
   }
}
// The example displays the following output:
//    'dog' precedes 'is'.
//    'The island has beautiful birds.' does not match the pattern.
//    'The pitch missed home plate.' does not match the pattern.
//    'Sunday' precedes 'is'.
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b\w+(?=\sis\b)"
        Dim inputs() As String = {"The dog is a Malamute.", _
                                   "The island has beautiful birds.", _
                                   "The pitch missed home plate.", _
                                   "Sunday is a weekend day."}

        For Each input As String In inputs
            Dim match As Match = Regex.Match(input, pattern)
            If match.Success Then
                Console.WriteLine("'{0}' precedes 'is'.", match.Value)
            Else
                Console.WriteLine("'{0}' does not match the pattern.", input)
            End If
        Next
    End Sub
End Module
' The example displays the following output:
'       'dog' precedes 'is'.
'       'The island has beautiful birds.' does not match the pattern.
'       'The pitch missed home plate.' does not match the pattern.
'       'Sunday' precedes 'is'.

Regex \b\w+(?=\sis\b) ditafsirkan seperti yang diperlihatkan dalam tabel berikut.

Pola Deskripsi
\b Memulai pencocokan dalam batas kata.
\w+ Mencocokkan satu atau beberapa karakter kata.
(?=\sis\b) Tentukan apakah karakter kata diikuti oleh karakter whitespace dan string "adalah", yang berakhir pada batas kata. Jika demikian, kecocokan berhasil.

Pernyataan lookahead negatif lebar-nol

Konstruksi pengelompokan berikut mendefinisikan pernyataan lookahead negatif lebar nol:

(?!subekspresi)

Di sini, subekspresi adalah pola ekspresi reguler apa pun. Agar kecocokan berhasil, string input harus tidak cocok dengan pola regex dalam subekspresi, meskipun substring yang cocok tidak disertakan dalam hasil pencocokan.

Pernyataan lookahead negatif lebar nol biasanya digunakan entah di awal atau di akhir regex. Pada awal regex, ia dapat menentukan pola tertentu yang tidak boleh dicocokkan ketika awal regex mendefinisikan pola yang serupa tetapi lebih umum untuk dicocokkan. Dalam hal ini, sering digunakan untuk membatasi backtracking. Pada akhir regex, itu dapat menentukan subekspresi yang tidak dapat terjadi pada akhir pencocokan.

Contoh berikut mendefinisikan regex yang menggunakan pernyataan lookahead lebar nol di awal regex untuk mencocokkan kata-kata yang tidak dimulai dengan "un".

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(?!un)\w+\b";
      string input = "unite one unethical ethics use untie ultimate";
      foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
         Console.WriteLine(match.Value);
   }
}
// The example displays the following output:
//       one
//       ethics
//       use
//       ultimate
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b(?!un)\w+\b"
        Dim input As String = "unite one unethical ethics use untie ultimate"
        For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
            Console.WriteLine(match.Value)
        Next
    End Sub
End Module
' The example displays the following output:
'       one
'       ethics
'       use
'       ultimate

Regex \b(?!un)\w+\b ditafsirkan seperti yang diperlihatkan dalam tabel berikut.

Pola Deskripsi
\b Memulai pencocokan dalam batas kata.
(?!un) Tentukan apakah dua karakter berikutnya adalah "un". Jika tidak, kecocokan mungkin terjadi.
\w+ Mencocokkan satu atau beberapa karakter kata.
\b Mengakhiri pencocokan dalam batas kata.

Contoh berikut mendefinisikan regex yang menggunakan pernyataan lookahead lebar nol di akhir regex untuk mencocokkan kata-kata yang tidak diakhiri dengan karakter tanda baca.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b\w+\b(?!\p{P})";
      string input = "Disconnected, disjointed thoughts in a sentence fragment.";
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine(match.Value);
   }
}
// The example displays the following output:
//       disjointed
//       thoughts
//       in
//       a
//       sentence
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b\w+\b(?!\p{P})"
        Dim input As String = "Disconnected, disjointed thoughts in a sentence fragment."
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine(match.Value)
        Next
    End Sub
End Module
' The example displays the following output:
'       disjointed
'       thoughts
'       in
'       a
'       sentence

Regex \b\w+\b(?!\p{P}) ditafsirkan seperti yang diperlihatkan dalam tabel berikut.

Pola Deskripsi
\b Memulai pencocokan dalam batas kata.
\w+ Mencocokkan satu atau beberapa karakter kata.
\b Mengakhiri pencocokan dalam batas kata.
\p{P}) Jika karakter berikutnya bukan simbol tanda baca (seperti titik atau koma), pencocokan berhasil.

Pernyataan lookbehind positif lebar-nol

Konstruksi pengelompokan berikut mendefinisikan pernyataan lookbehind positif lebar nol:

(?<=subekspresi)

Di sini, subekspresi adalah pola ekspresi reguler apa pun. Agar kecocokan berhasil, subekspresi harus terjadi pada string input di sebelah kiri posisi saat ini, meskipun subexpression tidak disertakan dalam hasil pencocokan. Pernyataan lookbehind positif lebar nol tidak mundur.

Pernyataan lookbehind positif lebar nol biasanya digunakan pada awal regex. Pola yang mereka definisikan adalah prasyarat untuk pencocokan, meskipun itu bukan bagian dari hasil pencocokan.

Misalnya, contoh berikut cocok dengan dua digit terakhir tahun ini untuk abad kedua puluh satu (yaitu, mengharuskan digit "20" mendahului string yang cocok).

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "2010 1999 1861 2140 2009";
      string pattern = @"(?<=\b20)\d{2}\b";

      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine(match.Value);
   }
}
// The example displays the following output:
//       10
//       09
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim input As String = "2010 1999 1861 2140 2009"
        Dim pattern As String = "(?<=\b20)\d{2}\b"

        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine(match.Value)
        Next
    End Sub
End Module
' The example displays the following output:
'       10
'       09

Pola regex (?<=\b20)\d{2}\b ditafsirkan seperti yang ditunjukkan pada tabel berikut.

Pola Deskripsi
\d{2} Cocokkan dua digit desimal.
(?<=\b20) Lanjutkan pencocokan jika dua digit desimal didahului oleh digit desimal "20" pada batas kata.
\b Mengakhiri pencocokan dalam batas kata.

Pernyataan lookbehind positif lebar nol juga digunakan untuk membatasi backtracking ketika karakter atau karakter terakhir dalam grup yang ditangkap harus merupakan subset dari karakter yang cocok dengan pola regex grup tersebut. Misalnya, jika grup menangkap semua karakter kata berturut-turut, Anda dapat menggunakan pernyataan lookbehind positif lebar nol untuk mengharuskan karakter terakhir menjadi alfabetik.

Pernyataan lookbehind negatif lebar-nol

Konstruksi pengelompokan berikut mendefinisikan pernyataan lookbehind negatif lebar nol:

(?<!subekspresi)

Di sini, subekspresi adalah pola ekspresi reguler apa pun. Agar kecocokan berhasil, subekspresi tidak boleh terjadi pada string input di sebelah kiri posisi saat ini. Namun, substring apa pun yang tidak cocok dengan subexpression tidak disertakan dalam hasil pencocokan.

Pernyataan lookbehind negatif lebar nol biasanya digunakan pada awal regex. Pola yang mereka definisikan menghalangi kecocokan dalam string berikutnya. Mereka juga digunakan untuk membatasi backtracking ketika karakter atau karakter terakhir dalam grup yang ditangkap tidak boleh merupakan satu atau lebih karakter yang cocok dengan pola regex grup itu. Misalnya, jika grup menangkap semua karakter kata berturut-turut, Anda dapat menggunakan pernyataan lookbehind positif lebar nol untuk mengharuskan karakter terakhir tidak menjadi garis bawah (_).

Contoh berikut cocok dengan tanggal untuk setiap hari dalam seminggu yang bukan akhir pekan (yaitu, itu bukan Sabtu atau Minggu).

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string[] dates = { "Monday February 1, 2010",
                         "Wednesday February 3, 2010",
                         "Saturday February 6, 2010",
                         "Sunday February 7, 2010",
                         "Monday, February 8, 2010" };
      string pattern = @"(?<!(Saturday|Sunday) )\b\w+ \d{1,2}, \d{4}\b";

      foreach (string dateValue in dates)
      {
         Match match = Regex.Match(dateValue, pattern);
         if (match.Success)
            Console.WriteLine(match.Value);
      }
   }
}
// The example displays the following output:
//       February 1, 2010
//       February 3, 2010
//       February 8, 2010
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim dates() As String = {"Monday February 1, 2010", _
                                  "Wednesday February 3, 2010", _
                                  "Saturday February 6, 2010", _
                                  "Sunday February 7, 2010", _
                                  "Monday, February 8, 2010"}
        Dim pattern As String = "(?<!(Saturday|Sunday) )\b\w+ \d{1,2}, \d{4}\b"

        For Each dateValue As String In dates
            Dim match As Match = Regex.Match(dateValue, pattern)
            If match.Success Then
                Console.WriteLine(match.Value)
            End If
        Next
    End Sub
End Module
' The example displays the following output:
'       February 1, 2010
'       February 3, 2010
'       February 8, 2010

Pola regex (?<!(Saturday|Sunday) )\b\w+ \d{1,2}, \d{4}\b ditafsirkan seperti yang ditunjukkan pada tabel berikut.

Pola Deskripsi
\b Memulai pencocokan dalam batas kata.
\w+ Cocokkan satu atau beberapa karakter kata diikuti oleh karakter whitespace.
\d{1,2}, Cocokkan satu atau dua digit desimal diikuti dengan karakter whitespace dan koma.
\d{4}\b Cocokkan empat digit desimal, dan akhiri kecocokan pada batas kata.
(?<!(Saturday|Sunday) ) Jika kecocokan didahului oleh sesuatu selain string "Sabtu" atau "Minggu" diikuti oleh spasi, kecocokan berhasil.

Kelompok atom

Konstruksi pengelompokan berikut mewakili grup atom (dikenal di beberapa mesin regex lainnya sebagai subekspresi nonbacktracking, subekspresi atom, atau subekspresi sekali saja):

(?>subekspresi)

Di sini, subekspresi adalah pola ekspresi reguler apa pun.

Biasanya, jika regex menyertakan pola pencocokan opsional atau alternatif dan kecocokan tidak berhasil, mesin regex dapat bercabang ke berbagai arah untuk mencocokkan string input dengan pola. Jika kecocokan tidak ditemukan saat mengambil cabang pertama, mesin regex dapat mencadangkan atau mundur ke titik di mana ia mengambil kecocokan pertama dan mencoba pencocokan menggunakan cabang kedua. Proses ini dapat berlanjut hingga semua cabang telah dicoba.

Konstruksi bahasa (?>subekspresi) menonaktifkan backtracking. Mesin regex akan mencocokkan dengan sebanyak mungkin karakter dalam string input. Ketika tidak ada pencocokan lebih lanjut yang mungkin, itu tidak akan mundur untuk mencoba pencocokan pola alternatif. (Artinya, subekspresi hanya cocok dengan string yang akan dicocokkan dengan subekspresi saja; tidak berusaha mencocokkan string berdasarkan subekspresi dan subekspresi apa pun yang mengikutinya.)

Opsi ini disarankan jika Anda tahu bahwa backtracking tidak akan berhasil. Mencegah mesin regex melakukan pencarian yang tidak perlu meningkatkan performa.

Contoh berikut menggambarkan bagaimana grup atom memodifikasi hasil kecocokan pola. Regex mundur berhasil mencocokkan serangkaian karakter berulang diikuti oleh satu kejadian lagi dari karakter yang sama pada batas kata, tetapi regex nonbacktracking tidak.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string[] inputs = { "cccd.", "aaad", "aaaa" };
      string back = @"(\w)\1+.\b";
      string noback = @"(?>(\w)\1+).\b";

      foreach (string input in inputs)
      {
         Match match1 = Regex.Match(input, back);
         Match match2 = Regex.Match(input, noback);
         Console.WriteLine("{0}: ", input);

         Console.Write("   Backtracking : ");
         if (match1.Success)
            Console.WriteLine(match1.Value);
         else
            Console.WriteLine("No match");

         Console.Write("   Nonbacktracking: ");
         if (match2.Success)
            Console.WriteLine(match2.Value);
         else
            Console.WriteLine("No match");
      }
   }
}
// The example displays the following output:
//    cccd.:
//       Backtracking : cccd
//       Nonbacktracking: cccd
//    aaad:
//       Backtracking : aaad
//       Nonbacktracking: aaad
//    aaaa:
//       Backtracking : aaaa
//       Nonbacktracking: No match
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim inputs() As String = {"cccd.", "aaad", "aaaa"}
        Dim back As String = "(\w)\1+.\b"
        Dim noback As String = "(?>(\w)\1+).\b"

        For Each input As String In inputs
            Dim match1 As Match = Regex.Match(input, back)
            Dim match2 As Match = Regex.Match(input, noback)
            Console.WriteLine("{0}: ", input)

            Console.Write("   Backtracking : ")
            If match1.Success Then
                Console.WriteLine(match1.Value)
            Else
                Console.WriteLine("No match")
            End If

            Console.Write("   Nonbacktracking: ")
            If match2.Success Then
                Console.WriteLine(match2.Value)
            Else
                Console.WriteLine("No match")
            End If
        Next
    End Sub
End Module
' The example displays the following output:
'    cccd.:
'       Backtracking : cccd
'       Nonbacktracking: cccd
'    aaad:
'       Backtracking : aaad
'       Nonbacktracking: aaad
'    aaaa:
'       Backtracking : aaaa
'       Nonbacktracking: No match

Regex nonbacktracking (?>(\w)\1+).\b didefinisikan seperti yang ditunjukkan pada tabel berikut ini.

Pola Deskripsi
(\w) Cocokkan satu karakter kata dan tetapkan ke grup penangkap pertama.
\1+ Cocokkan nilai substring pertama yang ditangkap satu kali atau lebih.
. Cocokkan karakter apa pun.
\b Akhiri pencocokan pada batas kata.
(?>(\w)\1+) Cocokkan satu atau beberapa kemunculan karakter kata duplikat, tetapi jangan mundur untuk mencocokkan karakter terakhir pada batas kata.

Konstruksi pengelompokan dan objek ekspresi reguler

Substring yang dicocokkan dengan grup pengambilan regex diwakili oleh objek System.Text.RegularExpressions.Group, yang dapat diambil dari objek System.Text.RegularExpressions.GroupCollection yang dikembalikan oleh properti Match.Groups. Objek GroupCollection diisi sebagai berikut:

  • Objek Group pertama dalam koleksi (objek pada indeks nol) mewakili seluruh kecocokan.
  • Kumpulan objek Group berikutnya mewakili grup penangkapan yang tidak bernama (bernomor). Mereka muncul dalam urutan di mana mereka didefinisikan dalam regex, dari kiri ke kanan. Nilai indeks dari grup-grup ini berkisar dari 1 hingga jumlah grup penangkap yang tidak bernama dalam koleksi. (Indeks grup tertentu setara dengan backreference bernomornya. Untuk informasi selengkapnya tentang backreference, lihat Konstruksi Backreference.)
  • Kumpulan objek Group akhir mewakili grup penangkapan bernama. Mereka muncul dalam urutan di mana mereka didefinisikan dalam regex, dari kiri ke kanan. Nilai indeks dari grup penangkap bernama pertama adalah lebih besar satu dari indeks grup penangkap terakhir yang tidak bernama. Jika tidak ada kelompok penangkap yang tidak bernama dalam regex, nilai indeks dari grup penangkap bernama pertama adalah satu.

Jika Anda menerapkan pembilang ke grup penangkapan, properti objek Group, Capture.Value, Capture.Index,dan Capture.Length yang sesuai mencerminkan substring terakhir yang ditangkap oleh grup penangkapan. Anda dapat mengambil sekumpulan substring lengkap yang ditangkap oleh grup yang memiliki pembilang dari objek CaptureCollection yang dikembalikan oleh properti Group.Captures.

Contoh berikut mengklarifikasi hubungan antara objek Group dan Capture.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"(\b(\w+)\W+)+";
      string input = "This is a short sentence.";
      Match match = Regex.Match(input, pattern);
      Console.WriteLine("Match: '{0}'", match.Value);
      for (int ctr = 1; ctr < match.Groups.Count; ctr++)
      {
         Console.WriteLine("   Group {0}: '{1}'", ctr, match.Groups[ctr].Value);
         int capCtr = 0;
         foreach (Capture capture in match.Groups[ctr].Captures)
         {
            Console.WriteLine("      Capture {0}: '{1}'", capCtr, capture.Value);
            capCtr++;
         }
      }
   }
}
// The example displays the following output:
//       Match: 'This is a short sentence.'
//          Group 1: 'sentence.'
//             Capture 0: 'This '
//             Capture 1: 'is '
//             Capture 2: 'a '
//             Capture 3: 'short '
//             Capture 4: 'sentence.'
//          Group 2: 'sentence'
//             Capture 0: 'This'
//             Capture 1: 'is'
//             Capture 2: 'a'
//             Capture 3: 'short'
//             Capture 4: 'sentence'
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "(\b(\w+)\W+)+"
        Dim input As String = "This is a short sentence."
        Dim match As Match = Regex.Match(input, pattern)
        Console.WriteLine("Match: '{0}'", match.Value)
        For ctr As Integer = 1 To match.Groups.Count - 1
            Console.WriteLine("   Group {0}: '{1}'", ctr, match.Groups(ctr).Value)
            Dim capCtr As Integer = 0
            For Each capture As Capture In match.Groups(ctr).Captures
                Console.WriteLine("      Capture {0}: '{1}'", capCtr, capture.Value)
                capCtr += 1
            Next
        Next
    End Sub
End Module
' The example displays the following output:
'       Match: 'This is a short sentence.'
'          Group 1: 'sentence.'
'             Capture 0: 'This '
'             Capture 1: 'is '
'             Capture 2: 'a '
'             Capture 3: 'short '
'             Capture 4: 'sentence.'
'          Group 2: 'sentence'
'             Capture 0: 'This'
'             Capture 1: 'is'
'             Capture 2: 'a'
'             Capture 3: 'short'
'             Capture 4: 'sentence'

Pola ekspresi reguler (\b(\w+)\W+)+ mengekstrak kata individual dari string. Ini didefinisikan seperti yang ditunjukkan pada tabel berikut.

Pola Deskripsi
\b Memulai pencocokan dalam batas kata.
(\w+) Mencocokkan satu atau beberapa karakter kata. Bersama-sama, karakter-karakter ini membentuk sebuah kata. Ini adalah grup pengambilan kedua.
\W+ Cocokkan satu atau beberapa karakter non-kata.
(\b(\w+)\W+) Cocokkan pola satu atau beberapa karakter kata diikuti oleh satu atau lebih karakter non-kata satu kali atau lebih. Ini adalah grup penangkapan pertama.

Kelompok penangkap kedua cocok dengan setiap kata kalimat. Kelompok penangkap pertama cocok dengan setiap kata bersama dengan tanda baca dan whitespace yang mengikuti kata tersebut. Objek Group yang indeksnya adalah 2 menyediakan informasi tentang teks yang cocok dengan grup pengambilan kedua. Kumpulan kata lengkap yang diambil oleh grup penangkapan tersedia dari objek CaptureCollection yang dikembalikan oleh properti Group.Captures.

Lihat juga