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.
- Valideer tekst om ervoor te zorgen dat deze overeenkomt met een vooraf gedefinieerd patroon (zoals een e-mailadres).
- Tekstsubtekenreeksen 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 extra functies toevoegt, zoals van rechts naar links overeenkomend. 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:
Bepaal of het reguliere expressiepatroon voorkomt in de invoertekst door de methode aan te Regex.IsMatch roepen. Zie Procedure voor een voorbeeld dat gebruikmaakt van de methode voor het IsMatch valideren van tekst : Controleren of tekenreeksen een geldige e-mailindeling hebben.
Haal een of alle exemplaren van tekst op die overeenkomt met het reguliere expressiepatroon door de Regex.Match of Regex.Matches methode aan te roepen. De vorige methode retourneert een System.Text.RegularExpressions.Match object dat informatie geeft over de overeenkomende tekst. Deze laatste retourneert een MatchCollection object dat één System.Text.RegularExpressions.Match object bevat voor elke overeenkomst die in de geparseerde tekst wordt gevonden.
Vervang tekst die overeenkomt met het reguliere expressiepatroon door de Regex.Replace methode aan te roepen. Voor voorbeelden die de Replace methode gebruiken om datumnotaties te wijzigen en ongeldige tekens uit een tekenreeks te verwijderen, raadpleegt u Procedure: Ongeldige tekens verwijderen uit een tekenreeks en voorbeeld: Datumnotaties wijzigen.
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 niet-vertrouwde invoer gebruikt, geeft u een time-out door. Een kwaadwillende gebruiker kan invoer opgeven voor RegularExpressions
een Denial-of-Service-aanval. ASP.NET Core Framework-API's die gebruikmaken van RegularExpressions
een time-out.
Tip
De System.Web.RegularExpressions naamruimte bevat een aantal reguliere expressieobjecten waarmee vooraf gedefinieerde reguliere expressiepatronen worden geïmplementeerd 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 elk exemplaar 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("{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
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 woordtekens, maar zo weinig mogelijk tekens. Samen vormen ze een groep die kan worden aangeduid als \1 . |
\s |
Overeenkomst met een spatieteken. |
\1 |
Komt overeen met de subtekenreeks die gelijk is aan de groep met de naam \1 . |
\b |
Komt overeen met een woordgrens. |
De Regex.Matches methode wordt aangeroepen met reguliere expressieopties ingesteld op RegexOptions.IgnoreCase. De overeenkomstbewerking is daarom niet hoofdlettergevoelig en het voorbeeld identificeert de subtekenreeks '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 object gebruikt het NumberFormatInfo object om de notatie 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 deze de subgroep die alleen de numerieke tekenreeks bevat, converteert deze naar een Decimal waarde en berekent het een voorlopig 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 {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.
Op een computer waarvan de huidige cultuur Engels is - Verenigde Staten (en-US), wordt de reguliere expressie \$\s*[-+]?([0-9]{0,3}(,[0-9]{3})*(\.[0-9]+)?)
dynamisch gebouwd. 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. Alleen $ het symbool geeft aan dat de engine voor reguliere expressies moet proberen te beginnen met de overeenkomst aan het einde van een tekenreeks. 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 exemplaren van een spatieteken. |
[-+]? |
Zoek naar nul of één exemplaar van een positief of negatief teken. |
([0-9]{0,3}(,[0-9]{3})*(\.[0-9]+)?) |
De buitenste haakjes definiëren deze expressie als een vastleggende 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 volledige overeenkomst. |
[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 exemplaar van het decimaalteken, gevolgd door ten minste één decimaalteken. |
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.
Verwante artikelen:
Title | 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 van gedrag van reguliere expressie | Biedt informatie over de mogelijkheden en het gedrag van reguliere .NET-expressies. |
Reguliere expressies gebruiken in Visual Studio |