Wyrażenia regularne platformy .NET

Wyrażenia regularne zapewniają zaawansowaną, elastyczną i wydajną metodę przetwarzania tekstu. Obszerna notacja dopasowywania wzorców w wyrażeniach regularnych umożliwia szybkie analizowanie dużych ilości tekstu na:

  • Znajdź określone wzorce znaków.
  • Zweryfikuj tekst, aby upewnić się, że jest zgodny ze wstępnie zdefiniowanym wzorcem (np. adresem e-mail).
  • Wyodrębnianie, edytowanie, zastępowanie lub usuwanie podciągów tekstowych.
  • Dodaj wyodrębnione ciągi do kolekcji, aby wygenerować raport.

W przypadku wielu aplikacji, które zajmują się ciągami lub analizowania dużych bloków tekstu, wyrażenia regularne są niezbędnym narzędziem.

Jak działają wyrażenia regularne

Centralnym elementem przetwarzania tekstu z wyrażeniami regularnymi jest aparat wyrażeń regularnych, który jest reprezentowany przez System.Text.RegularExpressions.Regex obiekt na platformie .NET. Przetwarzanie tekstu przy użyciu wyrażeń regularnych wymaga co najmniej, aby aparat wyrażeń regularnych był dostarczany z następującymi dwoma elementami informacji:

  • Wzorzec wyrażenia regularnego do zidentyfikowania w tekście.

    Na platformie .NET wzorce wyrażeń regularnych są definiowane przez specjalną składnię lub język, który jest zgodny z wyrażeniami regularnymi Perl 5 i dodaje kilka dodatkowych funkcji, takich jak dopasowywanie od prawej do lewej. Aby uzyskać więcej informacji, zobacz Język wyrażeń regularnych — szybka dokumentacja.

  • Tekst do analizy dla wzorca wyrażenia regularnego.

Metody Regex klasy umożliwiają wykonywanie następujących operacji:

Aby zapoznać się z omówieniem modelu obiektu wyrażenia regularnego, zobacz Model obiektów wyrażeń regularnych.

Aby uzyskać więcej informacji na temat języka wyrażeń regularnych, zobacz Język wyrażeń regularnych — szybki przewodnik lub pobierz i wydrukuj jedną z następujących broszur:

Przykłady wyrażeń regularnych

Klasa String zawiera metody wyszukiwania ciągów i zastępowania, których można użyć, gdy chcesz zlokalizować ciągi literału w większym ciągu. Wyrażenia regularne są najbardziej przydatne, gdy chcesz zlokalizować jeden z kilku podciągów w większym ciągu lub gdy chcesz zidentyfikować wzorce w ciągu, jak pokazano w poniższych przykładach.

Ostrzeżenie

W przypadku używania System.Text.RegularExpressions metody do przetwarzania niezaufanych danych wejściowych należy przekazać limit czasu. Złośliwy użytkownik może przekazać dane wejściowe , RegularExpressionspowodując atak typu "odmowa usługi". ASP.NET podstawowe interfejsy API platformy, które używają RegularExpressions przekroczenia limitu czasu.

Napiwek

System.Web.RegularExpressions Przestrzeń nazw zawiera wiele obiektów wyrażeń regularnych, które implementują wstępnie zdefiniowane wzorce wyrażeń regularnych na potrzeby analizowania ciągów z dokumentów HTML, XML i ASP.NET. Na przykład TagRegex klasa identyfikuje tagi początkowe w ciągu, a CommentRegex klasa identyfikuje ASP.NET komentarze w ciągu.

Przykład 1. Zastępowanie podciągów

Załóżmy, że lista wysyłkowa zawiera nazwy, które czasami zawierają tytuł (Pani, Pani lub Pani) wraz z imieniem i nazwiskiem. Załóżmy, że nie chcesz dołączać tytułów podczas generowania etykiet kopert z listy. W takim przypadku możesz użyć wyrażenia regularnego, aby usunąć tytuły, jak pokazano w poniższym przykładzie:

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = "(Mr\\.? |Mrs\\.? |Miss |Ms\\.? )";
      string[] names = { "Mr. Henry Hunt", "Ms. Sara Samuels",
                         "Abraham Adams", "Ms. Nicole Norris" };
      foreach (string name in names)
         Console.WriteLine(Regex.Replace(name, pattern, String.Empty));
   }
}
// The example displays the following output:
//    Henry Hunt
//    Sara Samuels
//    Abraham Adams
//    Nicole Norris
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "(Mr\.? |Mrs\.? |Miss |Ms\.? )"
        Dim names() As String = {"Mr. Henry Hunt", "Ms. Sara Samuels", _
                                  "Abraham Adams", "Ms. Nicole Norris"}
        For Each name As String In names
            Console.WriteLine(Regex.Replace(name, pattern, String.Empty))
        Next
    End Sub
End Module
' The example displays the following output:
'    Henry Hunt
'    Sara Samuels
'    Abraham Adams
'    Nicole Norris

Wzorzec (Mr\.? |Mrs\.? |Miss |Ms\.? ) wyrażenia regularnego pasuje do dowolnego wystąpienia "Pan", "Pan", "Pani", "Pani", "Miss", "Pani", "Pani" lub "Pani". Wywołanie Regex.Replace metody zastępuje dopasowany ciąg String.Emptyciągiem ; innymi słowy, usuwa go z oryginalnego ciągu.

Przykład 2. Identyfikowanie zduplikowanych wyrazów

Przypadkowe duplikowanie wyrazów jest typowym błędem, który tworzą autorzy. Użyj wyrażenia regularnego, aby zidentyfikować zduplikowane wyrazy, jak pokazano w poniższym przykładzie:

using System;
using System.Text.RegularExpressions;

public class Class1
{
   public static void Main()
   {
      string pattern = @"\b(\w+?)\s\1\b";
      string input = "This this is a nice day. What about this? This tastes good. I saw a a dog.";
      foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
         Console.WriteLine("{0} (duplicates '{1}') at position {2}",
                           match.Value, match.Groups[1].Value, match.Index);
   }
}
// The example displays the following output:
//       This this (duplicates 'This') at position 0
//       a a (duplicates 'a') at position 66
Imports System.Text.RegularExpressions

Module modMain
    Public Sub Main()
        Dim pattern As String = "\b(\w+?)\s\1\b"
        Dim input As String = "This this is a nice day. What about this? This tastes good. I saw a a dog."
        For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
            Console.WriteLine("{0} (duplicates '{1}') at position {2}", _
                              match.Value, match.Groups(1).Value, match.Index)
        Next
    End Sub
End Module
' The example displays the following output:
'       This this (duplicates 'This') at position 0
'       a a (duplicates 'a') at position 66

Wzorzec \b(\w+?)\s\1\b wyrażenia regularnego można interpretować w następujący sposób:

Wzorzec Interpretacja
\b Rozpoczyna na granicy wyrazu.
(\w+?) Dopasuj co najmniej jeden znak słowa, ale jak najmniejszą liczbę znaków. Razem tworzą grupę, która może być nazywana .\1
\s Dopasowuje znak odstępu.
\1 Dopasuj podciąg, który jest równy grupie o nazwie \1.
\b Dopasowuje granicę wyrazu.

Metoda jest wywoływana Regex.Matches przy użyciu opcji wyrażeń regularnych ustawionych na RegexOptions.IgnoreCasewartość . W związku z tym operacja dopasowania jest niewrażliwa na wielkość liter, a przykład identyfikuje podciąg "To to" jako duplikację.

Ciąg wejściowy zawiera podciąg "to? To". Jednak ze względu na interweniujący znak interpunkcyjny nie jest identyfikowany jako duplikacja.

Przykład 3. Dynamiczne tworzenie wyrażenia regularnego wrażliwego na kulturę

Poniższy przykład ilustruje moc wyrażeń regularnych w połączeniu z elastycznością oferowaną przez program . Funkcje globalizacji platformy NET. Używa NumberFormatInfo obiektu do określenia formatu wartości walutowych w bieżącej kulturze systemu. Następnie używa tych informacji do dynamicznego konstruowania wyrażenia regularnego, które wyodrębnia wartości waluty z tekstu. Dla każdego dopasowania wyodrębnia podgrupę zawierającą tylko ciąg liczbowy, konwertuje ją na wartość i oblicza sumę bieżącą Decimal .

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      // Define text to be parsed.
      string input = "Office expenses on 2/13/2008:\n" +
                     "Paper (500 sheets)                      $3.95\n" +
                     "Pencils (box of 10)                     $1.00\n" +
                     "Pens (box of 10)                        $4.49\n" +
                     "Erasers                                 $2.19\n" +
                     "Ink jet printer                        $69.95\n\n" +
                     "Total Expenses                        $ 81.58\n";

      // Get current culture's NumberFormatInfo object.
      NumberFormatInfo nfi = CultureInfo.CurrentCulture.NumberFormat;
      // Assign needed property values to variables.
      string currencySymbol = nfi.CurrencySymbol;
      bool symbolPrecedesIfPositive = nfi.CurrencyPositivePattern % 2 == 0;
      string groupSeparator = nfi.CurrencyGroupSeparator;
      string decimalSeparator = nfi.CurrencyDecimalSeparator;

      // Form regular expression pattern.
      string pattern = Regex.Escape( symbolPrecedesIfPositive ? currencySymbol : "") +
                       @"\s*[-+]?" + "([0-9]{0,3}(" + groupSeparator + "[0-9]{3})*(" +
                       Regex.Escape(decimalSeparator) + "[0-9]+)?)" +
                       (! symbolPrecedesIfPositive ? currencySymbol : "");
      Console.WriteLine( "The regular expression pattern is:");
      Console.WriteLine("   " + pattern);

      // Get text that matches regular expression pattern.
      MatchCollection matches = Regex.Matches(input, pattern,
                                              RegexOptions.IgnorePatternWhitespace);
      Console.WriteLine("Found {0} matches.", matches.Count);

      // Get numeric string, convert it to a value, and add it to List object.
      List<decimal> expenses = new List<Decimal>();

      foreach (Match match in matches)
         expenses.Add(Decimal.Parse(match.Groups[1].Value));

      // Determine whether total is present and if present, whether it is correct.
      decimal total = 0;
      foreach (decimal value in expenses)
         total += value;

      if (total / 2 == expenses[expenses.Count - 1])
         Console.WriteLine("The expenses total {0:C2}.", expenses[expenses.Count - 1]);
      else
         Console.WriteLine("The expenses total {0:C2}.", total);
   }
}
// The example displays the following output:
//       The regular expression pattern is:
//          \$\s*[-+]?([0-9]{0,3}(,[0-9]{3})*(\.[0-9]+)?)
//       Found 6 matches.
//       The expenses total $81.58.
Imports System.Collections.Generic
Imports System.Globalization
Imports System.Text.RegularExpressions

Public Module Example
    Public Sub Main()
        ' Define text to be parsed.
        Dim input As String = "Office expenses on 2/13/2008:" + vbCrLf + _
                              "Paper (500 sheets)                      $3.95" + vbCrLf + _
                              "Pencils (box of 10)                     $1.00" + vbCrLf + _
                              "Pens (box of 10)                        $4.49" + vbCrLf + _
                              "Erasers                                 $2.19" + vbCrLf + _
                              "Ink jet printer                        $69.95" + vbCrLf + vbCrLf + _
                              "Total Expenses                        $ 81.58" + vbCrLf
        ' Get current culture's NumberFormatInfo object.
        Dim nfi As NumberFormatInfo = CultureInfo.CurrentCulture.NumberFormat
        ' Assign needed property values to variables.
        Dim currencySymbol As String = nfi.CurrencySymbol
        Dim symbolPrecedesIfPositive As Boolean = CBool(nfi.CurrencyPositivePattern Mod 2 = 0)
        Dim groupSeparator As String = nfi.CurrencyGroupSeparator
        Dim decimalSeparator As String = nfi.CurrencyDecimalSeparator

        ' Form regular expression pattern.
        Dim pattern As String = Regex.Escape(CStr(IIf(symbolPrecedesIfPositive, currencySymbol, ""))) + _
                                "\s*[-+]?" + "([0-9]{0,3}(" + groupSeparator + "[0-9]{3})*(" + _
                                Regex.Escape(decimalSeparator) + "[0-9]+)?)" + _
                                CStr(IIf(Not symbolPrecedesIfPositive, currencySymbol, ""))
        Console.WriteLine("The regular expression pattern is: ")
        Console.WriteLine("   " + pattern)

        ' Get text that matches regular expression pattern.
        Dim matches As MatchCollection = Regex.Matches(input, pattern, RegexOptions.IgnorePatternWhitespace)
        Console.WriteLine("Found {0} matches. ", matches.Count)

        ' Get numeric string, convert it to a value, and add it to List object.
        Dim expenses As New List(Of Decimal)

        For Each match As Match In matches
            expenses.Add(Decimal.Parse(match.Groups.Item(1).Value))
        Next

        ' Determine whether total is present and if present, whether it is correct.
        Dim total As Decimal
        For Each value As Decimal In expenses
            total += value
        Next

        If total / 2 = expenses(expenses.Count - 1) Then
            Console.WriteLine("The expenses total {0:C2}.", expenses(expenses.Count - 1))
        Else
            Console.WriteLine("The expenses total {0:C2}.", total)
        End If
    End Sub
End Module
' The example displays the following output:
'       The regular expression pattern is:
'          \$\s*[-+]?([0-9]{0,3}(,[0-9]{3})*(\.[0-9]+)?)
'       Found 6 matches.
'       The expenses total $81.58.

Na komputerze, na którym bieżąca kultura to angielski — Stany Zjednoczone (en-US), przykład dynamicznie tworzy wyrażenie \$\s*[-+]?([0-9]{0,3}(,[0-9]{3})*(\.[0-9]+)?)regularne . Ten wzorzec wyrażenia regularnego można interpretować w następujący sposób:

Wzorzec Interpretacja
\$ Wyszukaj pojedyncze wystąpienie symbolu dolara ($) w ciągu wejściowym. Ciąg wzorca wyrażenia regularnego zawiera ukośnik odwrotny wskazujący, że symbol dolara ma być interpretowany dosłownie, a nie jako kotwica wyrażenia regularnego. Sam $ symbol wskazuje, że aparat wyrażeń regularnych powinien spróbować rozpocząć dopasowanie na końcu ciągu. Aby upewnić się, że symbol waluty bieżącej kultury nie jest błędnie interpretowany jako symbol wyrażenia regularnego, przykład wywołuje Regex.Escape metodę ucieczki od znaku.
\s* Wyszukaj zero lub więcej wystąpień znaku odstępu.
[-+]? Wyszukaj zero lub jedno wystąpienie znaku dodatniego lub ujemnego.
([0-9]{0,3}(,[0-9]{3})*(\.[0-9]+)?) Nawiasy zewnętrzne definiują to wyrażenie jako grupę przechwytywania lub podwyrażenie. Jeśli zostanie znalezione dopasowanie, informacje o tej części pasującego ciągu można pobrać z drugiego Group obiektu w GroupCollection obiekcie zwróconym Match.Groups przez właściwość. Pierwszy element w kolekcji reprezentuje całe dopasowanie.
[0-9]{0,3} Wyszukaj zero do trzech wystąpień cyfr dziesiętnych od 0 do 9.
(,[0-9]{3})* Wyszukaj zero lub więcej wystąpień separatora grupy, po którym następuje trzy cyfry dziesiętne.
\. Poszukaj pojedynczego wystąpienia separatora dziesiętnego.
[0-9]+ Wyszukaj co najmniej jedną cyfrę dziesiętną.
(\.[0-9]+)? Wyszukaj zero lub jedno wystąpienie separatora dziesiętnego, po którym następuje co najmniej jedna cyfra dziesiętna.

Jeśli każdy podwzorca zostanie znaleziony w ciągu wejściowym, dopasowanie powiedzie się, a Match obiekt zawierający informacje o dopasowaniu MatchCollection zostanie dodany do obiektu.

Nazwa opis
Język wyrażeń regularnych — podręczny wykaz Zawiera informacje na temat zestawu znaków, operatorów i konstrukcji, których można użyć do definiowania wyrażeń regularnych.
Model obiektów wyrażeń regularnych Zawiera informacje i przykłady kodu ilustrujące sposób używania klas wyrażeń regularnych.
Szczegóły dotyczące zachowania wyrażeń regularnych Zawiera informacje o możliwościach i zachowaniu wyrażeń regularnych platformy .NET.
Używanie wyrażeń regularnych w programie Visual Studio

Odwołanie