Reguljära .NET-uttryck

Reguljära uttryck ger en kraftfull, flexibel och effektiv metod för bearbetning av text. Med den omfattande notationen mönstermatchning av reguljära uttryck kan du snabbt parsa stora mängder text för att:

  • Hitta specifika teckenmönster.
  • Verifiera text för att säkerställa att den matchar ett fördefinierat mönster (till exempel en e-postadress).
  • Extrahera, redigera, ersätta eller ta bort textundersträngar.
  • Lägg till extraherade strängar i en samling för att generera en rapport.

För många program som hanterar strängar eller som parsar stora textblock är reguljära uttryck ett oumbärligt verktyg.

Så här fungerar reguljära uttryck

Mittpunkten i textbearbetning med reguljära uttryck är motorn för reguljära uttryck, som representeras av System.Text.RegularExpressions.Regex objektet i .NET. Som minst kräver bearbetning av text med reguljära uttryck att motorn för reguljära uttryck tillhandahålls med följande två informationsobjekt:

  • Mönster för reguljära uttryck som ska identifieras i texten.

    I .NET definieras mönster för reguljära uttryck av en särskild syntax eller ett särskilt språk, som är kompatibelt med reguljära Perl 5-uttryck och lägger till ytterligare funktioner som matchning från höger till vänster. Mer information finns i Språk för reguljära uttryck – snabbreferens.

  • Texten som ska parsas för det reguljära uttrycksmönstret.

Med klassmetoderna Regex kan du utföra följande åtgärder:

En översikt över objektmodellen för reguljära uttryck finns i Objektmodellen för reguljära uttryck.

Mer information om reguljärt uttrycksspråk finns i Språk för reguljära uttryck – snabbreferens eller ladda ned och skriva ut någon av följande broschyrer:

Exempel på reguljära uttryck

Klassen String innehåller strängsöknings- och ersättningsmetoder som du kan använda när du vill hitta literalsträngar i en större sträng. Reguljära uttryck är mest användbara antingen när du vill hitta en av flera delsträngar i en större sträng eller när du vill identifiera mönster i en sträng, som följande exempel illustrerar.

Varning

När du använder System.Text.RegularExpressions för att bearbeta ej betrodda indata skickar du en timeout. En obehörig användare kan ange indata till RegularExpressions, vilket orsakar en Denial-of-Service-attack. ASP.NET Core Framework-API:er som använder RegularExpressions passera en timeout.

Dricks

Namnområdet System.Web.RegularExpressions innehåller ett antal reguljära uttrycksobjekt som implementerar fördefinierade mönster för reguljära uttryck för parsning av strängar från HTML-, XML- och ASP.NET-dokument. Klassen identifierar till exempel TagRegex starttaggar i en sträng och CommentRegex klassen identifierar ASP.NET kommentarer i en sträng.

Exempel 1: Ersätt understrängar

Anta att en e-postlista innehåller namn som ibland innehåller en titel (Mr. , Mrs., Miss eller Ms.) tillsammans med ett för- och efternamn. Anta att du inte vill ta med rubrikerna när du genererar kuvertetiketter från listan. I så fall kan du använda ett reguljärt uttryck för att ta bort rubrikerna, vilket visas i följande exempel:

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

Det reguljära uttryckets mönster (Mr\.? |Mrs\.? |Miss |Ms\.? ) matchar varje förekomst av "Mr ", "Mr", "Mrs ", "Mrs. ", "Miss ", "Ms ", eller "Ms. ". Anropet Regex.Replace till metoden ersätter den matchade strängen med String.Empty, med andra ord, den tar bort den från den ursprungliga strängen.

Exempel 2: Identifiera duplicerade ord

Att oavsiktligt duplicera ord är ett vanligt fel som författare gör. Använd ett reguljärt uttryck för att identifiera duplicerade ord, som följande exempel visar:

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

Mönstret \b(\w+?)\s\1\b för reguljära uttryck kan tolkas på följande sätt:

Mönster Tolkning
\b Börja vid en ordgräns.
(\w+?) Matcha ett eller flera ordtecken, men så få tecken som möjligt. Tillsammans bildar de en grupp som kan kallas \1.
\s Matcha ett blankstegstecken.
\1 Matcha den delsträng som är lika med gruppen med namnet \1.
\b Matcha en ordgräns.

Metoden Regex.Matches anropas med reguljära uttrycksalternativ inställda på RegexOptions.IgnoreCase. Därför är matchningsåtgärden skiftlägeskänslig och exemplet identifierar delsträngen "This this" (Detta är detta) som en duplicering.

Indatasträngen innehåller delsträngen "this? Det här". Men på grund av intervenerande skiljetecken identifieras det inte som en duplicering.

Exempel 3: Skapa ett kulturkänsligt reguljärt uttryck dynamiskt

I följande exempel visas kraften i reguljära uttryck i kombination med flexibiliteten som erbjuds av . NET:s globaliseringsfunktioner. Det använder NumberFormatInfo objektet för att fastställa formatet för valutavärden i systemets aktuella kultur. Den använder sedan den informationen för att dynamiskt konstruera ett reguljärt uttryck som extraherar valutavärden från texten. För varje matchning extraheras den undergrupp som endast innehåller den numeriska strängen, konverterar den till ett Decimal värde och beräknar en löpande summa.

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.

På en dator vars nuvarande kultur är engelska – USA (en-US) bygger exemplet dynamiskt det reguljära uttrycket \$\s*[-+]?([0-9]{0,3}(,[0-9]{3})*(\.[0-9]+)?). Det här reguljära uttrycksmönstret kan tolkas på följande sätt:

Mönster Tolkning
\$ Leta efter en enskild förekomst av dollarsymbolen ($) i indatasträngen. Mönstersträngen för reguljära uttryck innehåller ett omvänt snedstreck som anger att dollarsymbolen ska tolkas bokstavligen snarare än som ett reguljärt uttrycksankare. Enbart symbolen $ skulle indikera att motorn för reguljära uttryck bör försöka starta sin matchning i slutet av en sträng. För att säkerställa att den aktuella kulturens valutasymbol inte misstolkas som en reguljär uttryckssymbol anropar Regex.Escape exemplet metoden för att undkomma tecknet.
\s* Leta efter noll eller fler förekomster av ett blankstegstecken.
[-+]? Leta efter noll eller en förekomst av antingen ett positivt eller negativt tecken.
([0-9]{0,3}(,[0-9]{3})*(\.[0-9]+)?) De yttre parenteserna definierar det här uttrycket som en samlande grupp eller en underuttryck. Om en matchning hittas kan information om den här delen av matchande sträng hämtas från det andra Group objektet i objektet GroupCollection som returneras av Match.Groups egenskapen. Det första elementet i samlingen representerar hela matchningen.
[0-9]{0,3} Leta efter noll till tre förekomster av decimaltalen 0 till 9.
(,[0-9]{3})* Leta efter noll eller fler förekomster av en gruppavgränsare följt av tre decimaler.
\. Leta efter en enskild förekomst av decimalavgränsaren.
[0-9]+ Leta efter en eller flera decimaler.
(\.[0-9]+)? Leta efter noll eller en förekomst av decimalavgränsaren följt av minst en decimalsiffra.

Om varje undermönster hittas i indatasträngen lyckas matchningen och ett Match objekt som innehåller information om matchningen läggs till i MatchCollection objektet.

Title Description
Språk för reguljärt uttryck – snabbreferens Innehåller information om de tecken, operatorer och konstruktioner som du kan använda för att definiera reguljära uttryck.
Objektmodell för reguljärt uttryck Innehåller information och kodexempel som illustrerar hur du använder reguljära uttrycksklasser.
Information om beteende för reguljära uttryck Innehåller information om funktionerna och beteendet för reguljära .NET-uttryck.
Använda reguljära uttryck i Visual Studio

Referens