정규식 예: HREF 스캐닝
다음 예제는 입력 문자열을 검색하고 모든 href="…" 값과 문자열에서의 해당 위치를 보여 줍니다.
Warning
System.Text.RegularExpressions를 사용하여 신뢰할 수 없는 입력을 처리하는 경우 시간 제한을 전달합니다. 악의적인 사용자가 RegularExpressions
에 대한 입력을 제공하여 서비스 거부 공격을 일으킬 수 있습니다. RegularExpressions
를 사용하는 ASP.NET Core Framework 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* |
0개 이상의 공백 문자가 일치하는지 확인합니다. |
= |
등호와 일치합니다. |
\s* |
0개 이상의 공백 문자가 일치하는지 확인합니다. |
(?: |
캡처하지 않는 그룹을 시작합니다. |
["'](?<1>[^"']*)["'] |
따옴표 또는 아포스트로피를 일치시키고 그 뒤에 따옴표나 아포스트로피 이외의 문자와 일치하는 캡처링 그룹이 오고 그 뒤에 따옴표나 아포스트로피가 옵니다. 1 이라는 그룹이 이 패턴에 포함됩니다. |
| | 이전 식 또는 다음 식과 일치하는 부울 OR입니다. |
(?<1>[^>\s]+) |
보다 큼 기호나 공백 문자 이외의 모든 문자와 일치시키기 위해 부정 집합을 사용하는 캡처링 그룹입니다. 1 이라는 그룹이 이 패턴에 포함됩니다. |
) |
캡처하지 않는 그룹을 종료합니다. |
일치 결과 클래스
검색 결과는 Match 클래스에 저장되는데, 이 클래스는 검색에서 추출한 모든 부분 문자열에 대한 액세스를 제공합니다. 또한 검색 중인 문자열 및 사용 중인 정규식을 기억하므로 Match.NextMatch 메서드를 호출하여 마지막 검색이 종료된 위치부터 또 다른 검색을 수행할 수 있습니다.
명시적으로 명명된 캡처
기존의 정규식에서 캡처링 괄호는 자동으로 순서대로 번호가 매겨집니다. 이 경우에 두 가지 문제가 발생합니다. 첫째, 괄호를 삽입하거나 제거하여 정규식을 수정하면 번호가 매겨진 캡처를 참조하는 모든 코드를 다시 작성하여 새로 지정된 번호를 반영해야 합니다. 둘째, 괄호의 다른 집합을 사용하여 허용 가능한 일치 항목에 두 개의 대체 식을 제공하기 때문에 둘 중 어느 쪽이 결과를 반환했는지 확인하기가 어려울 수 있습니다.
이러한 문제를 해결하기 위해 Regex 클래스는 (?<name>…)
구문이 지정된 슬롯에 일치 항목을 캡처하도록 지원합니다(문자열 또는 정수를 사용하여 슬롯에 이름을 지정할 수 있음. 정수를 더 신속하게 다시 호출할 수 있음). 따라서 동일한 문자열의 대체 일치 항목은 모두 동일한 위치로 지정될 수 있습니다. 충돌이 발생할 경우 슬롯에 삭제된 마지막 일치 항목이 성공적인 일치입니다. (그러나 단일 슬롯에 대한 여러 일치 항목이 있는 경우 전체 목록을 사용할 수 있습니다. 자세한 내용은 Group.Captures 컬렉션을 참조하세요.
참고 항목
.NET