Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В следующем примере выполняется поиск входной строки и отображается все href="..." значения и их расположения в строке.
Предупреждение
Неограниченное System.Text.RegularExpressions использование ненадежных входных данных может подвергать приложения атакам типа "отказ в обслуживании". См. статью Рекомендации по использованию регулярных выражений в .NET, чтобы узнать, как безопасно использовать регулярные выражения .NET с ненадёжными входными данными.
Объект Regex
Поскольку метод DumpHRefs можно вызывать несколько раз в пользовательском коде, он использует метод static (Shared в Visual Basic) 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]+)) показаны в следующей таблице.
| Pattern | Description |
|---|---|
href |
Соответствует литеральной строке "href". Совпадение не учитывает регистр. |
\s* |
Соответствует нулю или нескольким символам пробела. |
= |
Сопоставьте знак равенства. |
\s* |
Соответствует нулю или нескольким символам пробела. |
(?: |
Начните незахватывающую группу. |
["'](?<1>[^"']*)["'] |
Найдите соответствие для кавычки или апострофа, за которыми следует захватывающая группа, соответствующая любому символу, кроме кавычки или апострофа, а затем кавычка или апостроф. Группа с именем 1 входит в этот шаблон. |
| | | Логическое ИЛИ, которое соответствует либо предыдущему, либо следующему выражению. |
(?<1>[^>\s]+) |
Захватывающая группа, использующая отрицательный набор для сопоставления любого символа, кроме знака «больше» (>) или пробельного символа. Группа с именем 1 включена в этот шаблон. |
) |
Закройте незахватывающую группу. |
Класс результата сопоставления
Результаты поиска хранятся в Match классе, который предоставляет доступ ко всем подстрокам, извлеченным поиском. Он также запоминает искомую строку и используемое регулярное выражение, поэтому может вызвать метод Match.NextMatch, чтобы выполнить следующий поиск, начиная с того места, где закончился предыдущий.
Явно именованные захваты
В традиционных регулярных выражениях запись круглых скобок автоматически нумеруется последовательно. Это приводит к двум проблемам. Во-первых, если регулярное выражение изменяется путём добавления или удаления пары скобок, необходимо переписать весь код, который ссылается на пронумерованные группы захвата, с учётом новой нумерации. Во-вторых, поскольку различные наборы скобок часто используются для предоставления двух альтернативных выражений для допустимого совпадения, может быть трудно определить, какие из двух выражений фактически возвращают результат.
Чтобы устранить эти проблемы, класс Regex поддерживает синтаксис (?<name>…) для сохранения совпадения в указанном слоте (слоту можно присвоить имя в виде строки или целого числа; к слотам с целочисленными именами можно обращаться быстрее). Таким образом, альтернативные совпадения для одной и той же строки могут быть направлены в одно и то же место. В случае конфликта последнее совпадение, помещённое в слот, считается успешным совпадением. (Однако доступен полный список всех совпадений для одного слота. Дополнительные сведения см. в коллекции Group.Captures.)