Příklad regulárního výrazu: Vyhledávání HREF
Následující příklad prohledá vstupní řetězec a zobrazí všechny href="..." hodnoty a jejich umístění v řetězci.
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.
Objekt Regex
Vzhledem k tomu, že metodu DumpHRefs
lze volat vícekrát z uživatelského kódu, používá metodu static
(Shared
v jazyce Visual Basic). Regex.Match(String, String, RegexOptions) To umožňuje modulu regulárních výrazů ukládat regulární výraz do mezipaměti regulární výraz a vyhnout se režii vytvoření instance nového Regex objektu při každém zavolání metody. Objekt Match se pak použije k iteraci všech shod v řetězci.
private static void DumpHRefs(string inputString)
{
string hrefPattern = @"href\s*=\s*(?:[""'](?<1>[^""']*)[""']|(?<1>[^>\s]+))";
try
{
Match regexMatch = Regex.Match(inputString, hrefPattern,
RegexOptions.IgnoreCase | RegexOptions.Compiled,
TimeSpan.FromSeconds(1));
while (regexMatch.Success)
{
Console.WriteLine($"Found href {regexMatch.Groups[1]} at {regexMatch.Groups[1].Index}");
regexMatch = regexMatch.NextMatch();
}
}
catch (RegexMatchTimeoutException)
{
Console.WriteLine("The matching operation timed out.");
}
}
Private Sub DumpHRefs(inputString As String)
Dim hrefPattern As String = "href\s*=\s*(?:[""'](?<1>[^""']*)[""']|(?<1>[^>\s]+))"
Try
Dim regexMatch = Regex.Match(inputString, hrefPattern,
RegexOptions.IgnoreCase Or RegexOptions.Compiled,
TimeSpan.FromSeconds(1))
Do While regexMatch.Success
Console.WriteLine($"Found href {regexMatch.Groups(1)} at {regexMatch.Groups(1).Index}.")
regexMatch = regexMatch.NextMatch()
Loop
Catch e As RegexMatchTimeoutException
Console.WriteLine("The matching operation timed out.")
End Try
End Sub
Následující příklad pak ilustruje volání DumpHRefs
metody.
public static void Main()
{
string inputString = "My favorite web sites include:</P>" +
"<A HREF=\"https://learn.microsoft.com/en-us/dotnet/\">" +
".NET Documentation</A></P>" +
"<A HREF=\"http://www.microsoft.com\">" +
"Microsoft Corporation Home Page</A></P>" +
"<A HREF=\"https://devblogs.microsoft.com/dotnet/\">" +
".NET Blog</A></P>";
DumpHRefs(inputString);
}
// The example displays the following output:
// Found href https://learn.microsoft.com/dotnet/ at 43
// Found href http://www.microsoft.com at 114
// Found href https://devblogs.microsoft.com/dotnet/ at 188
Public Sub Main()
Dim inputString As String = "My favorite web sites include:</P>" &
"<A HREF=""https://learn.microsoft.com/en-us/dotnet/"">" &
".NET Documentation</A></P>" &
"<A HREF=""http://www.microsoft.com"">" &
"Microsoft Corporation Home Page</A></P>" &
"<A HREF=""https://devblogs.microsoft.com/dotnet/"">" &
".NET Blog</A></P>"
DumpHRefs(inputString)
End Sub
' The example displays the following output:
' Found href https://learn.microsoft.com/dotnet/ at 43
' Found href http://www.microsoft.com at 114
' Found href https://devblogs.microsoft.com/dotnet/ at 188
Vzor href\s*=\s*(?:["'](?<1>[^"']*)["']|(?<1>[^>\s]+))
regulárního výrazu je interpretován, jak je znázorněno v následující tabulce.
Vzor | Popis |
---|---|
href |
Porovná řetězec literálu "href". Shoda nerozlišuje malá a velká písmena. |
\s* |
Porovná žádný nebo více prázdných znaků. |
= |
Porovná znaménko rovná se. |
\s* |
Porovná žádný nebo více prázdných znaků. |
(?: |
Spusťte skupinu, která se nezachytává. |
["'](?<1>[^"']*)["'] |
Porovná uvozovky nebo apostrof následovanou zachytáváním skupiny, která odpovídá jakémukoli jinému znaku než uvozovky nebo apostrofu, následované uvozovkami nebo apostrofem. V tomto vzoru je zahrnuta skupina s názvem 1 . |
| | Logická hodnota OR, která odpovídá předchozímu výrazu nebo dalšímu výrazu. |
(?<1>[^>\s]+) |
Zachytávání skupiny, která používá negated sadu, aby odpovídala jakémukoli jinému znaku než znaménko větší než nebo prázdný znak. V tomto vzoru je zahrnuta skupina s názvem 1 . |
) |
Ukončete skupinu, která se nezachytí. |
Shoda s třídou výsledků
Výsledky hledání jsou uloženy ve Match třídě, která poskytuje přístup ke všem podřetěžců extrahovaným vyhledáváním. Pamatuje si také hledaný řetězec a použitý regulární výraz, takže může volat metodu Match.NextMatch k provedení dalšího hledání, které začíná tam, kde skončil poslední.
Explicitně pojmenované zachytávání
V tradičních regulárních výrazech se zachytávání závorek automaticky očísluje postupně. To vede ke dvěma problémům. Za prvé, pokud je regulární výraz upraven vložením nebo odebráním sady závorek, musí se veškerý kód odkazující na číslovaný zachytávání přepsat tak, aby odrážel nové číslování. Zadruhé, protože různé sady závorek se často používají k poskytnutí dvou alternativních výrazů pro přijatelnou shodu, může být obtížné určit, které z těchto dvou výrazů skutečně vrátily výsledek.
Aby se tyto problémy vyřešily, Regex třída podporuje syntaxi (?<name>…)
pro zachycení shody do zadaného slotu (slot lze pojmenovat pomocí řetězce nebo celého čísla; celá čísla lze odvolat rychleji). Proto lze alternativní shody pro stejný řetězec všechny směrovat na stejné místo. V případě konfliktu je úspěšná shoda poslední shoda vyřazená do slotu. (Úplný seznam více shod pro jeden slot je však k dispozici. Podrobnosti najdete v kolekci Group.Captures .)