規則運算式範例:掃描 HREF
下列範例將搜尋輸入字串,並顯示所有 href="..." 值和它們在字串中的位置。
警告
使用 System.Text.RegularExpressions 來處理不受信任的輸入時,請傳遞逾時。 惡意使用者可以提供輸入給 RegularExpressions
,導致拒絕服務的攻擊。 使用 RegularExpressions
的 ASP.NET Core 架構 API 會傳遞逾時。
Regex 物件
由於可從使用者程式碼多次呼叫 DumpHRefs
方法,因此它會使用 static
(在 Visual Basic 中為 Shared
) Regex.Match(String, String, RegexOptions) 方法。 這可讓規則運算式引擎快取規則運算式,並避免在每次呼叫方法時因將新 Regex 物件具現化而導致的額外負荷。 接著會使用 Match 物件逐一查看字串中的所有相符項目。
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
下列範例說明如何呼叫 DumpHRefs
方法。
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
規則運算式模式 href\s*=\s*(?:["'](?<1>[^"']*)["']|(?<1>[^>\s]+))
的解譯方式如下表所示。
模式 | 描述 |
---|---|
href |
比對常值字串 "href"。 該比對不區分大小寫。 |
\s* |
比對零個以上的空白字元。 |
= |
比對等號。 |
\s* |
比對零個以上的空白字元。 |
(?: |
啟動非擷取群組。 |
["'](?<1>[^"']*)["'] |
比對引號 (或單引號),後面接著符合引號 (或單引號) 以外的任何字元的擷取群組,再加上引號 (或單引號)。 此模式中包含名為 1 的群組。 |
| | 符合上一個運算式或下一個運算式的布林值 OR。 |
(?<1>[^>\s]+) |
擷取群組,此群組會使用否定集來比對任何大於正負號或空白字元以外的字元。 此模式中包含名為 1 的群組。 |
) |
結束非擷取群組。 |
比對結果類別
搜尋的結果會儲存在 Match 類別中,可讓您存取搜尋擷取的所有子字串。 它也會記住要搜尋的字串與所用的規則運算式,使其能呼叫 Match.NextMatch 方法,從最後一個搜尋結束的位置開始執行其他搜尋。
明確命名的擷取
在傳統的規則運算式中,會自動將擷取括號依序編號。 這會導致兩個問題。 第一,如果修改規則運算式時,是以插入或移除一組括號來進行,就必須重新撰寫所有參考已編號擷取的程式碼,以反映新的編號。 第二,不同的括號通常用來提供兩個替代運算式以進行可接受的比對,因此可能難以判斷這兩個運算式是哪一個實際傳回結果。
為了解決這些問題,Regex 類別支援 (?<name>…)
的語法,可將相符項目擷取至指定的位置 (該位置可以使用字串或整數命名;重新叫用整數的速度更快)。 因此,相同字串的所有替代比對皆可導向相同的位置。 萬一發生衝突時,最後一個進入位置的比對就是成功的比對 (不過,您可以使用單一位置之多個比對的完整清單。如需詳細資訊,請參閱 Group.Captures 集合。)
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應