Пример. Поиск ссылок HREF
В следующем примере показаны поиск и печать всех значений href="...", а также их позиций во входной строке.
Объект Regex
Поскольку метод DumpHRefs может быть вызван из пользовательского кода несколько раз, используется метод static (Shared в Visual Basic) Regex.Match(String, String, RegexOptions). Это позволяет кэшировать регулярное выражение и избежать дополнительной нагрузки, связанной с созданием объекта Regex при каждом вызове метода.. Объект Match используется для итерации по всем совпадениями в строке.
Private Sub DumpHRefs(inputString As String)
Dim m As Match
Dim HRefPattern As String = "href\s*=\s*(?:""(?<1>[^""]*)""|(?<1>\S+))"
m = Regex.Match(inputString, HRefPattern, _
RegexOptions.IgnoreCase Or RegexOptions.Compiled)
Do While m.Success
Console.WriteLine("Found href {0} at {1}.", _
m.Groups(1), m.Groups(1).Index)
m = m.NextMatch()
Loop
End Sub
private static void DumpHRefs(string inputString)
{
Match m;
string HRefPattern = "href\\s*=\\s*(?:\"(?<1>[^\"]*)\"|(?<1>\\S+))";
m = Regex.Match(inputString, HRefPattern,
RegexOptions.IgnoreCase | RegexOptions.Compiled);
while (m.Success)
{
Console.WriteLine("Found href " + m.Groups[1] + " at "
+ m.Groups[1].Index);
m = m.NextMatch();
}
}
В следующем примере демонстрируется вызов метода DumpHRefs.
Public Sub Main()
Dim inputString As String = "My favorite web sites include:</P>" & _
"<A HREF=""https://msdn2.microsoft.com"">" & _
"MSDN Home Page</A></P>" & _
"<A HREF=""https://www.microsoft.com"">" & _
"Microsoft Corporation Home Page</A></P>" & _
"<A HREF=""https://blogs.msdn.com/bclteam"">" & _
".NET Base Class Library blog</A></P>"
DumpHRefs(inputString)
End Sub
' The example displays the following output:
' Found href https://msdn2.microsoft.com at 43
' Found href https://www.microsoft.com at 102
' Found href https://blogs.msdn.com/bclteam/) at 176
public static void Main()
{
string inputString = "My favorite web sites include:</P>" +
"<A HREF=\"https://msdn2.microsoft.com\">" +
"MSDN Home Page</A></P>" +
"<A HREF=\"https://www.microsoft.com\">" +
"Microsoft Corporation Home Page</A></P>" +
"<A HREF=\"https://blogs.msdn.com/bclteam\">" +
".NET Base Class Library blog</A></P>";
DumpHRefs(inputString);
}
// The example displays the following output:
// Found href https://msdn2.microsoft.com at 43
// Found href https://www.microsoft.com at 102
// Found href https://blogs.msdn.com/bclteam at 176
Интерпретация шаблона регулярного выражения href\s*=\s*(?:"(?<1>[^""]*)"|(?<1>\S+)) показана в следующей таблице.
Шаблон |
Описание |
---|---|
href |
Совпадение с литеральной строкой "href". Сопоставление не учитывает регистр. |
\s* |
Сопоставить нулю или нескольким символам пробела. |
= |
Сопоставить знаку равенства. |
\s* |
Сопоставить нулю или нескольким символам пробела. |
(?:"(?<1>[^""]*)"|(?<1>\S+)) |
Сопоставить одному из следующих без назначения результата захваченной группе:
|
(?<1>[^"]*) |
Присвоить ноль или несколько вхождений любого символа, отличного от одиночной кавычки, захваченной группе с именем 1. |
"(?<1>\S+) |
Присвоить один или более символов, отличных от пробела, захваченной группе с именем 1. |
Класс результата поиска
Результаты поиска сохраняются в классе Match, который предоставляет доступ ко всем подстрокам, извлеченным в ходе поиска. Также запоминается искомая строка и используемое регулярное выражение, поэтому можно вызвать метод Match.NextMatch для выполнения другого поиска, начиная с того места, где закончился предыдущий.
Явно именованные шаблоны
В обычных регулярных выражениях круглые скобки, обозначающие отдельные шаблоны, автоматически последовательно нумеруются. В связи с этим возникают две проблемы. Во-первых, если регулярное выражение изменяется из-за вставки или удаления пары круглых скобок, все части кода, которые ссылаются на нумерованные шаблоны, необходимо переписать, чтобы отразить новую нумерацию. Во-вторых, вследствие того, что различные пары круглых скобок часто используются для определения двух альтернативных выражений для поиска, трудно определить, какое из двух выражений в действительности вернуло результат.
Для решения этих проблем класс Regex поддерживает синтаксис (?<name>…), с помощью которого найденный элемент можно сохранить в указанной ячейке (которой можно присвоить строковое имя или целочисленное обозначение; целые числа при этом работают быстрее). Таким образом, если шаблон будет найден повторно, он попадет в ту же ячейку. В случае конфликта последнее соответствие, помещенное в ячейку, является успешным. (Однако доступен и полный список соответствий для одной ячейки. Дополнительные сведения см. в коллекции Group.Captures.)