Delen via


Reguliere .NET-expressies

Reguliere expressies bieden een krachtige, flexibele en efficiënte methode voor het verwerken van tekst. Met de uitgebreide patroonkoppelings notatie van reguliere expressies kunt u snel grote hoeveelheden tekst parseren om:

  • Zoek specifieke tekenpatronen.
  • Tekst te valideren om ervoor te zorgen dat deze overeenkomt met een vooraf gedefinieerd patroon (zoals een e-mailadres).
  • Tekstgedeelten extraheren, bewerken, vervangen of verwijderen.
  • Voeg geëxtraheerde tekenreeksen toe aan een verzameling om een rapport te genereren.

Voor veel toepassingen die omgaan met tekenreeksen of die grote blokken tekst parseren, zijn reguliere expressies een onmisbaar hulpmiddel.

Hoe reguliere expressies werken

Het middenstuk van tekstverwerking met reguliere expressies is de reguliere expressie-engine, die wordt vertegenwoordigd door het System.Text.RegularExpressions.Regex object in .NET. Voor het verwerken van tekst met reguliere expressies moet de engine voor reguliere expressies minimaal de volgende twee gegevensitems bevatten:

  • Het reguliere expressiepatroon dat in de tekst moet worden geïdentificeerd.

    In .NET worden reguliere expressiepatronen gedefinieerd door een speciale syntaxis of taal, die compatibel is met reguliere Perl 5-expressies en enkele andere functies zoals van rechts naar links overeenkomende functies toevoegt. Zie Reguliere expressietaal - Snelzoekgids voor meer informatie.

  • De tekst die moet worden geparseerd voor het reguliere expressiepatroon.

Met de methoden van de Regex klasse kunt u de volgende bewerkingen uitvoeren:

Zie Het objectmodel reguliere expressie voor een overzicht van het reguliere expressieobjectmodel.

Zie Regular Expression Language - Snelzoekgids of download en druk een van de volgende brochures af voor meer informatie over de reguliere expressietaal:

Voorbeelden van reguliere expressies

De String klasse bevat zoek- en vervangingsmethoden voor tekenreeksen die u kunt gebruiken wanneer u letterlijke tekenreeksen in een grotere tekenreeks wilt zoeken. Reguliere expressies zijn het handigst als u een van de verschillende subtekenreeksen in een grotere tekenreeks wilt zoeken of als u patronen in een tekenreeks wilt identificeren, zoals in de volgende voorbeelden wordt geïllustreerd.

Waarschuwing

Wanneer u System.Text.RegularExpressions gebruikt om niet-vertrouwde invoer te verwerken, geeft u een time-out door. Een kwaadwillende gebruiker kan invoer opgeven voor RegularExpressionswaardoor een DoS-aanvalkan optreden. ASP.NET Core framework-API's die gebruikmaken van RegularExpressions geven een time-out door.

Hint

De System.Web.RegularExpressions naamruimte bevat veel reguliere expressieobjecten die vooraf gedefinieerde reguliere expressiepatronen implementeren voor het parseren van tekenreeksen uit HTML-, XML- en ASP.NET documenten. De TagRegex klasse identificeert bijvoorbeeld begintags in een tekenreeks en de CommentRegex klasse identificeert ASP.NET opmerkingen in een tekenreeks.

Voorbeeld 1: Subtekenreeksen vervangen

Stel dat een adressenlijst namen bevat die soms een titel bevatten (Mr., Mrs., Miss of Ms.) samen met een voor- en achternaam. Stel dat u de titels niet wilt opnemen wanneer u enveloplabels uit de lijst genereert. In dat geval kunt u een reguliere expressie gebruiken om de titels te verwijderen, zoals in het volgende voorbeeld wordt geïllustreerd:

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

Het reguliere expressiepatroon (Mr\.? |Mrs\.? |Miss |Ms\.? ) komt overeen met elke verschijning van "Mr ", "Mr. ", "Mrs ", "Mrs. ", "Miss ", "Ms ", of "Ms. ". De aanroep van de Regex.Replace methode vervangt de overeenkomende tekenreeks door String.Empty; met andere woorden, deze wordt verwijderd uit de oorspronkelijke tekenreeks.

Voorbeeld 2: Dubbele woorden identificeren

Het per ongeluk dupliceren van woorden is een veelvoorkomende fout die schrijvers maken. Gebruik een reguliere expressie om dubbele woorden te identificeren, zoals in het volgende voorbeeld wordt weergegeven:

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($"{match.Value} (duplicates '{match.Groups[1].Value}') at position {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

Het patroon van de reguliere expressie \b(\w+?)\s\1\b kan als volgt worden geïnterpreteerd:

Patroon Interpretatie
\b Begin bij een woordgrens.
(\w+?) Komt overeen met een of meer woordkarakters, maar zo min mogelijk tekens. Samen vormen ze een groep die kan worden aangeduid als \1.
\s Zoek een witruimtekarakter.
\1 Zoek de subtekenreeks die gelijk is aan de groep met de naam \1.
\b Vind een woordgrens.

De Regex.Matches methode wordt aangeroepen met reguliere expressieopties ingesteld op RegexOptions.IgnoreCase. De zoekbewerking is daarom niet hoofdlettergevoelig en het voorbeeld identificeert de deelstring 'Dit dit' als duplicatie.

De invoertekenreeks bevat de subtekenreeks "dit?" Dit". Vanwege het tussenliggende interpunctieteken wordt het echter niet geïdentificeerd als duplicatie.

Voorbeeld 3: Dynamisch een cultuurgevoelige reguliere expressie bouwen

In het volgende voorbeeld ziet u de kracht van reguliere expressies in combinatie met de flexibiliteit die wordt geboden door . De globalisatiefuncties van NET. Het gebruikt het NumberFormatInfo object om het formaat van valutawaarden in de huidige cultuur van het systeem te bepalen. Vervolgens wordt die informatie gebruikt om dynamisch een reguliere expressie te maken waarmee valutawaarden uit de tekst worden geëxtraheerd. Voor elke overeenkomst extraheert het de subgroep die alleen de numerieke tekenreeks bevat, converteert het deze naar een Decimal waarde en berekent het een lopend totaal.

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 {matches.Count} matches.");

      // 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 {expenses[expenses.Count - 1]:C2}.");
      else
         Console.WriteLine($"The expenses total {total:C2}.");
   }
}
// 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.

Op een computer waarvan de huidige cultuur Engels - Verenigde Staten is (en-US), bouwt het voorbeeld dynamisch de reguliere expressie \$\s*[-+]?([0-9]{0,3}(,[0-9]{3})*(\.[0-9]+)?). Dit reguliere expressiepatroon kan als volgt worden geïnterpreteerd:

Patroon Interpretatie
\$ Zoek naar één exemplaar van het dollarsymbool ($) in de invoertekenreeks. De tekenreeks voor het reguliere expressiepatroon bevat een backslash om aan te geven dat het dollarsymbool letterlijk moet worden geïnterpreteerd in plaats van als een anker voor reguliere expressies. Het $ symbool alleen geeft aan dat de reguliere expressie-engine moet proberen zijn overeenkomst aan het einde van een tekenreeks te starten. Om ervoor te zorgen dat het valutasymbool van de huidige cultuur niet verkeerd wordt geïnterpreteerd als een standaardexpressiesymbool, roept het voorbeeld de Regex.Escape methode aan om aan het teken te ontsnappen.
\s* Zoek naar nul of meer voorkomens van een witruimte karakter.
[-+]? Zoek naar nul of één voorkomst van een positief of negatief teken.
([0-9]{0,3}(,[0-9]{3})*(\.[0-9]+)?) De buitenste haakjes definiëren deze expressie als een capturerende groep of subexpressie. Als er een overeenkomst wordt gevonden, kan informatie over dit deel van de overeenkomende tekenreeks worden opgehaald uit het tweede Group object in het GroupCollection object dat door de Match.Groups eigenschap wordt geretourneerd. Het eerste element in de verzameling vertegenwoordigt de hele match.
[0-9]{0,3} Zoek naar nul tot drie exemplaren van de decimalen 0 tot en met 9.
(,[0-9]{3})* Zoek naar nul of meer exemplaren van een groepsscheidingsteken, gevolgd door drie decimale cijfers.
\. Zoek naar één exemplaar van het decimaalteken.
[0-9]+ Zoek een of meer decimale cijfers.
(\.[0-9]+)? Zoek naar nul of één voorkoming van het decimaalteken, gevolgd door ten minste één decimaal cijfer.

Als elk subpatroon wordt gevonden in de invoertekenreeks, slaagt de overeenkomst en wordt er een Match object met informatie over de overeenkomst toegevoegd aan het MatchCollection object.

Titel Beschrijving
Reguliere expressietaal - Snelzoekgids Bevat informatie over de set tekens, operators en constructies die u kunt gebruiken om reguliere expressies te definiëren.
Het objectmodel van de reguliere expressie Bevat informatie en codevoorbeelden die illustreren hoe u de reguliere expressieklassen gebruikt.
Details over het gebruik van reguliere expressies Biedt informatie over de mogelijkheden en het gedrag van reguliere .NET-expressies.
Reguliere expressies gebruiken in Visual Studio

Referentie