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é objemy textu na:
- Vyhledání konkrétních vzorů znaků
- Ověřte text, abyste zajistili, že odpovídá předdefinovanému vzoru (například e-mailové adrese).
- Extrahujte, upravte, nahraďte nebo odstraňte podřetězce textu.
- Přidejte extrahované řetězce do kolekce, 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 pomocí regulárních výrazů je modul regulárních výrazů, který je System.Text.RegularExpressions.Regex reprezentován objektem v rozhraní .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 najdete v tématu Jazyk regulárních výrazů – stručná referenční příručka.
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 pro ověřování textu, najdete v tématu Postupy: Ověření, že řetězce IsMatch 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 ke změně formátů data a odebrání neplatných znaků z řetězce, najdete v tématu Postupy: Odstranění neplatných znaků z řetězce Replace a Příklad: Změna formátů data.
Přehled objektového modelu regulárního výrazu najdete v tématu Objektový model regulárního výrazu.
Další informace o jazyce regulárních výrazů najdete v tématu Jazyk regulárních výrazů – stručné referenční informace nebo si stáhněte a vytiskněte jednu z těchto možností:
Příklady regulárních výrazů
Třída String zahrnuje celou řadu metod pro vyhledání nebo nahrazení řetězce, které lze ve větším řetězci použít při vyhledávání textových literálů. 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.
Upozornění
Při použití System.Text.RegularExpressions ke zpracování nedůvěryhodného vstupu předejte časový limit. Uživatel se zlými úmysly může poskytnout vstup pro RegularExpressions útok DoS (Denial-of-Service). Rozhraní API rozhraní ASP.NET Core Framework, která používají RegularExpressions předávat časový limit.
Tip
Obor názvů obsahuje řadu objektů regulárních výrazů, které implementují předdefinované vzory regulárních výrazů pro parsování řetězců z System.Web.RegularExpressions HTML, XML a ASP.NET dokumentů. Například třída identifikuje počáteční značky v řetězci a třída identifikuje ASP.NET TagRegex CommentRegex komentáře v řetězci.
Příklad 1: Nahrazení podřetězců
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.). Pokud při vytváření popisků ze seznamu nechcete oslovení zahrnout, můžete oslovení odstranit pomocí regulárního výrazu, jak je znázorněno v následujícím příkladu.
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 odpovídá libovolnému výskytu (Mr\.? |Mrs\.? |Miss |Ms\.? ) "Mr", "Mr. ", "Mrs ", "Mrs. ", "Miss ", "Ms nebo "Ms. ". 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í. Zdvojená slova mohou být vyhledána pomocí regulárního výrazu, jak znázorňuje 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 regulárního \b(\w+?)\s\1\b výrazu lze interpretovat takto:
| Vzor | Interpretace |
|---|---|
\b |
Začne na hranici slova. |
(\w+?) |
Porovná jeden nebo více znaků slova, ale co možná 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ězec, 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ězec "this? Tento“. Z důvodu výskytu otazníku však nedojde k vyhodnocení výrazu jako zdvojeného slova.
Příklad 3: Dynamické sestavení regulárního výrazu citlivého na jazykovou verzi
Následující příklad znázorňuje výkon 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.
Na počítači, jehož aktuální jazyková verze je angličtina – USA (en-US), příklad dynamicky sestaví 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 indikuje, že by se modul regulárních výrazů měl pokusit zahájit svou shodu na $ konci řetězce.) Aby se zajistilo, že symbol měny aktuální jazykové verze není přeinterpretován jako symbol regulárního výrazu, volá příklad metodu , která znak Regex.Escape řídicí. |
\s* |
Vyhledá žádný nebo několik výskytů znaku mezery. |
[-+]? |
Vyhledá žádný nebo jeden ze znaků plus nebo mínus. |
([0-9]{0,3}(,[0-9]{3})*(\.[0-9]+)?) |
Vnější závorky výrazu jej definují jako zachytávající skupinu nebo jako 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 celkovou 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 je v rámci vstupního řetězce každý z těchto dílčích vzorů vyhledán, dojde k nalezení shody a objekt Match, který obsahuje informaci o shodě, je přidán do objektu MatchCollection.
Související témata
| Nadpis | 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 Visual Studio |