Он пропустит и более сложный адрес:
text = "some-one.or.me@example.company.com";
Рассмотренный шаблон можно упростить (для парсера и, возможно, усложнить для человека), если заметить, что группа ([-.]\w+) используется дважды. Второе вхождение этой группы можно заменить ссылкой на первое ее появление. Это допустимо в рамках алгоритмов, использующих модель NFA.
Так как ссылка осуществляется по номеру, то важно правильно вычислить номер группы шаблона, на которую дается ссылка. Нулевая группа — это все выражение, первая группа — это содержимое внутри первой пары круглых скобок, вторая — второй, и т. д. Применяя эти рассуждения, получим другую форму шаблона:
pattern = @"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+\2*";
Здесь \2 — это ссылка на вторую группу шаблона, то есть на ([-.]\w+). Итак, пытаемся прочесть все выражение. Адрес email должен удовлетворять строке, которая:
Подстрока |
Смысл |
\w+ |
Начинается с одного или более элементов множества w (буквы плюс подчеркивание) |
[-+.] |
Может содержать один (или более) дефис или точку |
\w+ |
За которым следует один или более элементов множества w |
([-+.]\w+) |
Сформирована группа номер один |
([-+.]\w+)* |
Может содержать группу номер один |
@ |
Должна содержать символ @ |
\w+([-.]\w+)* |
Этот фрагмент расшифрован выше. Здесь появилась группа номер 2: ([-.]\w+) |
\. |
Должна содержать точку |
\w+ |
Содержит один или более элементов множества w |
\2* |
Может содержать группу номер 2 |
Используя таблицу операторов, вы легко вычислите, что строка (она приведена в MSDN):
pattern = @"([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)";
также может быть частью шаблона email. Она соответствует одному из вариантов записи адреса, когда почтовый сервер задан в цифровом формате TCP/IP адреса. Шаблон требует троекратного (или более) вхождения последовательностей вида "ddd.", где d — это цифра. Заметим, что его можно упростить:
pattern = @"(\d{1,3}\.){3,}";
Существует и другой способ записи этого шаблона: @"(\d{1,3}\.)\1\1", в котором дважды (\1\1) используется ссылка на группу (\d{1,3}\.). Номер 1 автоматически присвоен группе парсером.
Задержимся немного на определении диапазонов. Шаблон [0-35-9] фактически задает два поддиапазона [0-3] и [5-9]. Ему соответствуют все цифры, кроме цифры 4. Возникает желание оптимизировать выражение и записать его в виде [^4]. Однако, этот шаблон не эквивалентен первому, так как ему удовлетворяют не только цифры из [0-3] и [5-9], но и все другие символы.
Рассмотрим фрагмент кода, который демонстрирует, как работать с коллекциями объектов классов, задействованных в технологии регулярных выражений. Но сначала в шаблоне регулярного выражения обойдемся без групп (не считая нулевой, которая всегда присутствует).
text = "bitbitbit";
pattern = "bit"; // Ищем все вхождения "bit"
Regex ex = new Regex (pattern);
MatchCollection mc = ex.Matches(text); // Коллекция всех совпадений
Console.WriteLine (mc.Count > 0 ? ("There are "+mc.Count+" matches\n") : "No matches");
int nMatch = 0;
foreach (Match m in mc) // Проход по всей коллекции совпадений
{
Console.WriteLine (string.Format("{0}. Match: '{1}', Pos = {2}, {3} Groups",
++nMatch, m, m.Index, m.Groups.Count));
int nGroup = 0;
foreach (Group g in m.Groups) // Проход по всей коллекции групп
{
Console.WriteLine (string.Format(
"\t{0}. Group: '{1}', {2} Captures", nGroup++, g, g.Captures.Count));
foreach (Capture c in g.Captures) // Проход по всей коллекции захватов
Console.WriteLine (string.Format("\t\tCapture: '{0}', Pos = {1}", c, c.Index));
}
}
Этот фрагмент производит следующий, вполне очевидный вывод.
There are 3 matches
1. Match: 'bit', Pos = 0, 1 Groups
0. Group: 'bit', 1 Captures
Capture: 'bit', Pos = 0
2. Match: 'bit', Pos = 3, 1 Groups
0. Group: 'bit', 1 Captures
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.