Bagikan melalui


Konstruksi Perubahan dalam Regex

Konstruksi perubahan memodifikasi regex untuk mengaktifkan pencocokan either/or atau kondisional. .NET mendukung tiga konstruksi perubahan:

Pencocokan Pola dengan |

Anda dapat menggunakan karakter bilah vertikal (|) untuk mencocokkan salah satu dari serangkaian pola, di mana karakter | memisahkan setiap pola.

Seperti kelas karakter positif, karakter | dapat digunakan untuk mencocokkan salah satu dari sejumlah karakter tunggal. Contoh berikut menggunakan kelas karakter positif dan pencocokan pola either/or dengan karakter | untuk menemukan kemunculan kata "gray" atau "grey" dalam sebuah string. Dalam hal ini, karakter | menghasilkan regex yang lebih verbose.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      // Regular expression using character class.
      string pattern1 = @"\bgr[ae]y\b";
      // Regular expression using either/or.
      string pattern2 = @"\bgr(a|e)y\b";

      string input = "The gray wolf blended in among the grey rocks.";
      foreach (Match match in Regex.Matches(input, pattern1))
         Console.WriteLine("'{0}' found at position {1}",
                           match.Value, match.Index);
      Console.WriteLine();
      foreach (Match match in Regex.Matches(input, pattern2))
         Console.WriteLine("'{0}' found at position {1}",
                           match.Value, match.Index);
   }
}
// The example displays the following output:
//       'gray' found at position 4
//       'grey' found at position 35
//
//       'gray' found at position 4
//       'grey' found at position 35
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        ' Regular expression using character class.
        Dim pattern1 As String = "\bgr[ae]y\b"
        ' Regular expression using either/or.
        Dim pattern2 As String = "\bgr(a|e)y\b"

        Dim input As String = "The gray wolf blended in among the grey rocks."
        For Each match As Match In Regex.Matches(input, pattern1)
            Console.WriteLine("'{0}' found at position {1}", _
                              match.Value, match.Index)
        Next
        Console.WriteLine()
        For Each match As Match In Regex.Matches(input, pattern2)
            Console.WriteLine("'{0}' found at position {1}", _
                              match.Value, match.Index)
        Next
    End Sub
End Module
' The example displays the following output:
'       'gray' found at position 4
'       'grey' found at position 35
'       
'       'gray' found at position 4
'       'grey' found at position 35           

Regex yang menggunakan karakter |, \bgr(a|e)y\b, diinterpretasikan seperti yang ditunjukkan dalam tabel berikut:

Pola Deskripsi
\b Mulailah dari batas kata.
gr Cocokkan karakter "gr".
(a|e) Cocokkan "a" atau "e".
y\b Cocokkan "y" pada batas kata.

Karakter | juga dapat digunakan untuk melakukan pencocokan either/or dengan beberapa karakter atau subekspresi, yang dapat mencakup setiap kombinasi literal karakter dan elemen bahasa regex. (Kelas karakter tidak menyediakan fungsionalitas ini.) Contoh berikut menggunakan karakter | untuk mengekstrak Nomor Jaminan Sosial AS (SSN), yang merupakan angka 9 digit dengan format ddd-dd-dddd, atau Nomor Identifikasi Pemberi Kerja AS (EIN), yang merupakan angka 9 digit dengan format dd-ddddddd.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b";
      string input = "01-9999999 020-333333 777-88-9999";
      Console.WriteLine("Matches for {0}:", pattern);
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("   {0} at position {1}", match.Value, match.Index);
   }
}
// The example displays the following output:
//       Matches for \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b:
//          01-9999999 at position 0
//          777-88-9999 at position 22
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b"
        Dim input As String = "01-9999999 020-333333 777-88-9999"
        Console.WriteLine("Matches for {0}:", pattern)
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("   {0} at position {1}", match.Value, match.Index)
        Next
    End Sub
End Module
' The example displays the following output:
'       Matches for \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b:
'          01-9999999 at position 0
'          777-88-9999 at position 22

Regex \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b diinterpretasikan seperti yang ditunjukkan dalam tabel berikut:

Pola Deskripsi
\b Mulailah dari batas kata.
(\d{2}-\d{7}|\d{3}-\d{2}-\d{4}) Cocokkan salah satu dari berikut ini: dua digit desimal diikuti dengan tanda hubung yang diikuti dengan tujuh digit desimal; atau tiga digit desimal, tanda hubung, dua digit desimal, tanda hubung lain, dan empat digit desimal.
\b Mengakhiri pencocokan dalam batas kata.

Pencocokan kondisional dengan ekspresi

Elemen bahasa ini mencoba mencocokkan salah satu dari dua pola, tergantung pada apakah pola tersebut cocok dengan pola awal. Sintaksnya adalah:

(?(ekspresi)ya)

or

(?(ekspresi)ya|tidak)

di mana ekspresi adalah pola awal yang cocok, ya adalah pola yang cocok jika ekspresi cocok, dan tidak adalah pola opsional untuk dicocokkan jika ekspresi tidak cocok (jika pola tidak tidak disediakan, demikian setara dengan tidak kosong). Mesin regex memperlakukan ekspresi sebagai pernyataan lebar-nol; artinya, mesin regex tidak maju dalam aliran input setelah mengevaluasi ekspresi. Oleh karena itu, konstruksi ini setara dengan berikut:

(?(?=ekspresi)ya|tidak)

di mana (?=ekspresi) adalah konstruksi pernyataan lebar-nol. (Untuk informasi selengkapnya, lihat Konstruksi Pengelompokan.) Karena mesin regex menginterpretasikan ekspresi sebagai jangkar (pernyataan lebar-nol), ekspresi harus berupa pernyataan lebar-nol (untuk informasi selengkapnya, lihat Jangkar) atau subekspresi yang juga terkandung dalam ya. Jika tidak, pola ya tidak dapat dicocokkan.

Catatan

Jika ekspresi adalah grup penangkapan bernama atau bernomor, konstruksi perubahan diinterpretasikan sebagai uji tangkapan; untuk informasi selengkapnya, lihat bagian berikutnya, Pencocokan Kondisional Berdasarkan Grup Tangkapan yang Valid. Dengan kata lain, mesin regex tidak mencoba mencocokkan substring yang diambil, melainkan menguji ada atau tidaknya grup.

Contoh berikut adalah variasi contoh yang muncul di bagian Pencocokan Pola Either/Or dengan |. Ini menggunakan pencocokan kondisional untuk menentukan apakah tiga karakter pertama setalah batas kata adalah dua digit diikuti dengan tanda hubung. Jika ya, ia mencoba mencocokkan Nomor Identifikasi Pemberi Kerja (EIN) AS. Jika tidak, ia mencoba mencocokkan Nomor Jaminan Sosial AS (SSN).

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b";
      string input = "01-9999999 020-333333 777-88-9999";
      Console.WriteLine("Matches for {0}:", pattern);
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("   {0} at position {1}", match.Value, match.Index);
   }
}
// The example displays the following output:
//       Matches for \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b:
//          01-9999999 at position 0
//          777-88-9999 at position 22
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b"
        Dim input As String = "01-9999999 020-333333 777-88-9999"
        Console.WriteLine("Matches for {0}:", pattern)
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("   {0} at position {1}", match.Value, match.Index)
        Next
    End Sub
End Module
' The example displays the following output:
'       Matches for \b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b:
'          01-9999999 at position 0
'          777-88-9999 at position 22

Pola regex \b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b diinterpretasikan seperti yang ditunjukkan dalam tabel berikut:

Pola Deskripsi
\b Mulailah dari batas kata.
(?(\d{2}-) Tentukan apakah tiga karakter berikutnya terdiri dari dua digit diikuti dengan tanda hubung.
\d{2}-\d{7} Jika pola sebelumnya cocok, cocokkan dua digit diikuti dengan tanda hubung yang diikuti dengan tujuh digit.
\d{3}-\d{2}-\d{4} Jika pola sebelumnya tidak cocok, cocokkan tiga digit desimal, tanda hubung, dua digit desimal, tanda hubung lain, dan empat digit desimal.
\b Cocokkan batas kata.

Pencocokan kondisional berdasarkan grup yang diambil secara valid

Elemen bahasa ini mencoba mencocokkan salah satu dari dua pola tergantung pada apakah pola tersebut telah cocok dengan grup penangkapan yang ditentukan. Sintaksnya adalah:

(?(nama)ya)

or

(?(nama)ya|tidak)

or

(?(nomor)ya)

or

(?(nomor)ya|tidak)

di mana nama adalah nama dan angka adalah jumlah grup penangkapan, ya adalah ekspresi yang cocok jika nama atau angka memiliki kecocokan, dan tidak adalah ekspresi opsional yang cocok jika tidak (jika pola tidak tidak disediakan, demikian setara dengan tidak kosong).

Jika nama tidak sesuai dengan nama grup penangkapan yang digunakan dalam pola regex, konstruksi perubahan diinterpretasikan sebagai pengujian ekspresi, seperti yang dijelaskan di bagian sebelumnya. Biasanya, hal ini berarti ekspresi dievaluasi menjadi false. Jika angka tidak sesuai dengan grup penangkapan bernomor yang digunakan dalam pola regex, mesin regex akan menampilkan ArgumentException.

Contoh berikut adalah variasi contoh yang muncul di bagian Pencocokan Pola Either/Or dengan |. Ini menggunakan grup penangkapan bernama n2 yang terdiri atas dua digit diikuti dengan tanda hubung. Konstruksi perubahan menguji apakah grup penangkapan ini telah dicocokkan dalam string input. Jika sudah, konstruksi perubahan mencoba mencocokkan tujuh digit terakhir dari sembilan digit Nomor Identifikasi Pemberi Kerja AS (EIN). Jika belum, ia mencoba mencocokkan sembilan digit Nomor Jaminan Sosial AS (SSN).

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(?<n2>\d{2}-)?(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b";
      string input = "01-9999999 020-333333 777-88-9999";
      Console.WriteLine("Matches for {0}:", pattern);
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("   {0} at position {1}", match.Value, match.Index);
   }
}
// The example displays the following output:
//       Matches for \b(?<n2>\d{2}-)?(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b:
//          01-9999999 at position 0
//          777-88-9999 at position 22
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b(?<n2>\d{2}-)?(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b"
        Dim input As String = "01-9999999 020-333333 777-88-9999"
        Console.WriteLine("Matches for {0}:", pattern)
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("   {0} at position {1}", match.Value, match.Index)
        Next
    End Sub
End Module

Pola regex \b(?<n2>\d{2}-)?(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b diinterpretasikan seperti yang ditunjukkan dalam tabel berikut:

Pola Deskripsi
\b Mulailah dari batas kata.
(?<n2>\d{2}-)? Cocokkan nol atau satu kemunculan dua digit diikuti dengan tanda hubung. Beri nama grup penangkap ini n2.
(?(n2) Ujilah apakah n2 dicocokkan dalam string input.
\d{7} Jika n2 dicocokkan, cocokkan tujuh digit desimal.
|\d{3}-\d{2}-\d{4} Jika n2 tidak cocok, cocokkan tiga digit desimal, tanda hubung, dua digit desimal, tanda hubung lain, dan empat digit desimal.
\b Cocokkan batas kata.

Variasi dari contoh ini yang menggunakan grup bernomor alih-alih grup bernama ditunjukkan dalam contoh berikut. Pola regexnya adalah \b(\d{2}-)?(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(\d{2}-)?(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b";
      string input = "01-9999999 020-333333 777-88-9999";
      Console.WriteLine("Matches for {0}:", pattern);
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("   {0} at position {1}", match.Value, match.Index);
   }
}
// The example display the following output:
//       Matches for \b(\d{2}-)?(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b:
//          01-9999999 at position 0
//          777-88-9999 at position 22
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "\b(\d{2}-)?(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b"
        Dim input As String = "01-9999999 020-333333 777-88-9999"
        Console.WriteLine("Matches for {0}:", pattern)
        For Each match As Match In Regex.Matches(input, pattern)
            Console.WriteLine("   {0} at position {1}", match.Value, match.Index)
        Next
    End Sub
End Module
' The example displays the following output:
'       Matches for \b(\d{2}-)?(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b:
'          01-9999999 at position 0
'          777-88-9999 at position 22

Lihat juga