Regulární výrazy .NET
Regulární výrazy poskytují výkonný, flexibilní a efektivní způsob zpracování textu. Rozsáhlá notace porovnávání vzorů regulárních výrazů umožňuje rychle analyzovat velké množství textu na:
- Vyhledání konkrétních vzorů znaků
- Ověřte text a ujistěte se, že odpovídá předdefinovanému vzoru (například e-mailové adrese).
- Extrahování, úprava, nahrazení nebo odstranění podřetědců textu
- Přidejte do kolekce extrahované řetězce, aby se vygenerovala sestava.
Pro mnoho aplikací, které pracují s řetězci nebo které analyzují velké textové bloky, jsou regulární výrazy nepostradatelným nástrojem.
Jak fungují regulární výrazy
Středem zpracování textu s regulárními výrazy je modul regulárních výrazů, který je reprezentován objektem System.Text.RegularExpressions.Regex v .NET. Požadované minimum pro zpracování textu pomocí regulárních výrazů je předání následujících dvou informací modulu regulárních výrazů:
Vzor regulárního výrazu pro identifikaci v textu.
V .NET jsou vzory regulárních výrazů definovány speciální syntaxí nebo jazykem, který je kompatibilní s regulárními výrazy Perl 5 a přidává některé další funkce, jako je porovnávání zprava doleva. Další informace naleznete v tématu Jazyk regulárních výrazů – stručná referenční dokumentace.
Text určený k analýze pomocí vzoru regulárního výrazu.
Metody třídy Regex umožňují provedení následujících operací:
Určení toho, zda se ve vstupním textu objeví vzor regulárního výrazu po zavolání metody Regex.IsMatch. Příklad, který používá metodu IsMatch pro ověřování textu, viz Postupy: Ověření, zda řetězce jsou v platném formátu e-mailu.
Vrácení jednoho nebo všech výskytů textu, který se shoduje se vzorem regulárního výrazu, zavoláním metody Regex.Match nebo metody Regex.Matches. První metoda vrátí objekt System.Text.RegularExpressions.Match, který poskytuje informace o odpovídajícím textu. Druhá vrátí objekt MatchCollection, který obsahuje jeden objekt System.Text.RegularExpressions.Match pro jednotlivé shody v rámci analyzovaného textu.
Nahrazení textu, který odpovídá vzoru regulárního výrazu zavoláním metody Regex.Replace. Příklady, které používají metodu Replace ke změně formátů kalendářních dat a odebrání neplatných znaků z řetězce, najdete v tématu Postupy: Odstranění neplatných znaků z řetězce a příkladu: Změna formátů kalendářních dat.
Přehled objektového modelu regulárního výrazu naleznete v tématu Model objektu regulárního výrazu.
Další informace o jazyce regulárních výrazů naleznete v tématu Jazyk regulárních výrazů – stručná referenční dokumentace nebo stažení a tisk jedné z následujících brožur:
- Stručná referenční příručka ve formátu Wordu (.docx)
- Stručná referenční příručka ve formátu PDF (.pdf)
Příklady regulárních výrazů
Třída String obsahuje metody hledání a nahrazení řetězců, které můžete použít, když chcete vyhledat literály ve větším řetězci. Regulární výrazy jsou nejužitečnější při hledání jednoho nebo více dílčích podřetězců ve větším řetězci, nebo při identifikaci vzorů v řetězci, jak je znázorněno v následujícím příkladu.
Upozorňující
Při zpracování System.Text.RegularExpressions nedůvěryhodného vstupu předejte vypršení časového limitu. Uživatel se zlými úmysly může poskytnout vstup RegularExpressions
, což způsobí útok na dostupnost služby. ASP.NET rozhraní API architektury Core, která používají RegularExpressions
vypršení časového limitu.
Tip
Obor System.Web.RegularExpressions názvů obsahuje řadu objektů regulárních výrazů, které implementují předdefinované vzory regulárních výrazů pro analýzu řetězců z dokumentů HTML, XML a ASP.NET. Třída například TagRegex identifikuje počáteční značky v řetězci a CommentRegex třída identifikuje ASP.NET komentáře v řetězci.
Příklad 1: Nahrazení podřetědců
Předpokládejme seznam, který obsahuje jména a který může u jména a příjmení zahrnovat také oslovení (Mr., Mrs., Miss, nebo Ms.). Předpokládejme, že nechcete zahrnout názvy při generování štítků obálky ze seznamu. V takovém případě můžete k odebrání názvů použít regulární výraz, jak ukazuje následující příklad:
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
Vzor regulárního výrazu (Mr\.? |Mrs\.? |Miss |Ms\.? )
odpovídá jakémukoli výskytu výrazu "Mr", "Mr. ", "Paní", "Paní", "Slečna", "Slečna" nebo "Paní". Volání metody Regex.Replace nahradí vyhledaný řetězec String.Empty; jinými slovy to znamená, že jej z původního řetězce odstraní.
Příklad 2: Identifikace duplicitních slov
Nechtěně zdvojená slova jsou běžnou chybou, které se autoři při psaní dopouštějí. Regulární výraz použijte k identifikaci duplicitních slov, jak ukazuje následující příklad:
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
Vzor \b(\w+?)\s\1\b
regulárního výrazu lze interpretovat takto:
Vzor | Interpretace |
---|---|
\b |
Začne na hranici slova. |
(\w+?) |
Porovná jeden nebo více znaků slova, ale co nejvíce znaků. Společně tvoří skupinu, která může být označována jako \1 . |
\s |
Porovná prázdný znak. |
\1 |
Porovná podřetěžce, který se rovná skupině s názvem \1 . |
\b |
Porovná hranici slova. |
Metoda Regex.Matches je zavolána pomocí možností regulárního výrazu, které jsou nastaveny jako RegexOptions.IgnoreCase. Operace shody proto rozlišuje velká a malá písmena a příklad vyhodnotí podřetězec „Tento tento“ jako zdvojené slovo.
Vstupní řetězec obsahuje podřetězce "this? Tento“. Z důvodu intervenující interpunkční znaméně se ale jako duplicita neidentifikuje.
Příklad 3: Dynamické sestavení regulárního výrazu citlivého na jazykovou verzi
Následující příklad znázorňuje sílu regulárních výrazů v kombinaci s flexibilitou, kterou nabízí . Funkce globalizace technologie NET Formát měny v aktuální jazykové verzi systému určuje objekt NumberFormatInfo. Tuto informaci následně používá k vytvoření regulárního výrazu, který z textu extrahuje hodnoty měny. Pro jednotlivé shody extrahuje podskupinu obsahující pouze číselný řetězec, převede jej na hodnotu Decimal a vypočte mezisoučet.
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.
V počítači, jehož aktuální jazyková verze je angličtina - USA (en-US), příklad dynamicky vytváří regulární výraz \$\s*[-+]?([0-9]{0,3}(,[0-9]{3})*(\.[0-9]+)?)
. Tento vzor regulárního výrazu může být interpretován takto:
Vzor | Interpretace |
---|---|
\$ |
Ve vstupním řetězci vyhledejte jeden výskyt symbolu dolaru ($ ). Vzor regulárního výrazu obsahuje zpětné lomítko pro označení toho, zda bude symbol dolaru spíše interpretován doslovně, než aby byl použit jako ukotvení regulárního výrazu. Samotný $ symbol by značil, že modul regulárních výrazů by se měl pokusit zahájit shodu na konci řetězce. Aby se zajistilo, že symbol měny aktuální jazykové verze není chybně interpretován jako symbol regulárního výrazu, příklad volá metodu Regex.Escape pro řídicí znak. |
\s* |
Vyhledá žádný nebo několik výskytů znaku mezery. |
[-+]? |
Vyhledejte nulový nebo jeden výskyt kladného nebo záporného znaménka. |
([0-9]{0,3}(,[0-9]{3})*(\.[0-9]+)?) |
Vnější závorky definují tento výraz jako zachycenou skupinu nebo dílčí výraz. Při nalezení shody může být informace o části vyhovujícího řetězce vrácena druhým objektem Group v rámci objektu GroupCollection vráceného vlastností Match.Groups. První prvek v kolekci představuje celou shodu. |
[0-9]{0,3} |
Vyhledá žádný až tři výskyty desítkových číslic od 0 do 9. |
(,[0-9]{3})* |
Vyhledá žádný nebo několik výskytů oddělovače skupin, za kterým následují tři desítkové číslice. |
\. |
Vyhledá jeden výskyt oddělovače desetinných míst. |
[0-9]+ |
Vyhledá jednu nebo několik desítkových číslic. |
(\.[0-9]+)? |
Vyhledá žádný nebo jeden výskyt oddělovače desetinných míst následovaného alespoň jednou desítkovou číslicí. |
Pokud se každý podpattern nachází ve vstupním řetězci, shoda proběhne úspěšně a Match objekt, který obsahuje informace o shodě, se přidá do objektu MatchCollection .
Související články
Titulek | Popis |
---|---|
Jazyk regulárních výrazů – stručná referenční dokumentace | Poskytuje informace o sadách znaků, operátorech a konstrukcích, které lze použít pro definování regulárních výrazů. |
Model objektu regulárního výrazu | Poskytuje informace a příklady kódu znázorňující způsob používání tříd regulárních výrazů. |
Podrobnosti k chování regulárních výrazů | Poskytuje informace o možnostech a chování regulárních výrazů .NET. |
Použití regulárních výrazů v sadě Visual Studio |