Поиск и группирование

Если посмотреть на предыдущий пример, то все, что в нем происходит — это поиск по шаблону групп из десятичных цифр, разделенных точками, причем каждая группа может содержать от одной до трех цифр.

Речь о том, что такой грубый поиск обнаружит также соответствие и с некорректным IP-адресом вроде 999.888.777.666. Более совершенный поиск IP-адреса должен выглядеть следующим образом:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System;
using System.Text.RegularExpressions;
public class EntryPoint
{
static void Main( string[] args )  {
if ( args.Length < 1 )  {
Console.WriteLine( "Вы должны предоставить строку." );
return;
// Создать регулярное выражение для поиска шаблона IP-адреса,
string patterns @"([01]?\d\d?|2[0-4]\d|25[0-5])\." + @"([01]?\d\d?|2[0-4]\d|25[0-5])\." + в"([01]?\d\d?|2[0-4]\d|25[0-5])\." + @"([01]?\d\d?|2[0-4]\d|25[0-5])";
Regex regex = new Regex ( pattern ) ;
Match match = regex.Match( args[0] );
while ( match.Success )  {
Console.WriteLine ( "IP-адрес найден в позиции {0} со " + "значением {1}", match.Index, match.Value ) ;
match = match.NextMatch();
}

искового шаблона [01]?\d\d?|2[0-4]\d|25[0-5], разделенные точками, которые, конечно же, защищены. Каждое из этих подвыражений соответствует числу от 0 до 2552. Такое регулярное выражение для поиска IP-адреса уже намного лучше, хотя все еще не идеально. Однако с небольшой тонкой настройкой его можно использовать для верификации IP-адресов, переданных в строке.

Таким образом, регулярные выражения можно применять для эффективной верификации пользовательского ввода, гарантируя, что он будет соответствовать определенной форме. Например, существующий веб-сервер может ожидать ввода телефонных номеров США в формате (ххх) ххх-хххх.

Регулярные выражения позволяют легко проверять корректность ввода номеров пользователями.

Возможно, вы заметили, что в предыдущем примере в выражение поиска IP-адресов были добавлены скобки. Скобки используются для определения групп, формирующих подвыражения внутри общего регулярного выражения. Группы также могут содержать в себе другие группы.

Таким образом, шаблон регулярного выражения, описывающий IP-адрес в предыдущем примере, формирует группу для каждой части IP-адреса. К каждой индивидуальной группе внутри соответствия можно обращаться отдельно.

Рассмотрим модифицированную версию того же самого примера:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using system;
using system.text.regularexpressions;
public class entrypoint
{
static void main ( string[] args ) {
if ( args.length < 1 ) {
console.writeline ( "Вы должны предоставить строку." );
return;
}
// Создать регулярное выражение для поиска шаблона ip-адреса.
string pattern = @"([01]?\d\d?|2[0-4]\d|25[0-5])\." + @"([01]?\d\d?|2[0-4]\d|25[0-5])\." + @"([01]?\d\d?|2[0-4]\d|25[0-5])\." + @"([01]?\d\d?|2[0-4]\d|25[0-5])";
regex regex = new regex ( pattern ) ;
match match = regex.match( args[0] );
while ( match.Success )  {
Console.WriteLine ( "IP-адрес найден в позиции {0} со " + "значением {1}", match.Index, match.Value )/ Console.WriteLine( "Группы:" );
foreach( Group g in match.Groups ) {
Console.WriteLine( "\t{0} в позиции {1}", g.Value, g.Index ) ;
}
match = match.NextMatch();
}

Для каждого соответствия добавлен цикл, выполняющий итерацию по всем индивидуальным группам внутри соответствия. Как и можно было ожидать, в коллекции будет как минимум четыре группы, по одной для каждой части IP-адреса. Фактически, есть еще и пятый элемент группы — все совпадение. Таким образом, одна из групп внутри коллекции групп, возвращенных Match. Groups, всегда будет содержать само полное соответствие. Если запустить приведенный выше код со следующей строкой:

“Вот такой IP-адрес:123.123.1.123″

то результат будет таким:

IP-адрес найден в позиции 19 со значением 123.123.1.123 Группы:
123.123.1.123 в позиции 19
123 в позиции 19
123 в позиции 23
1 в позиции 27
123 в позиции 29

Группы предоставляют блестящую возможность указать части заданной входной строки. Например, в некоторый момент, выполняя верификацию формата пользовательского ввода телефонного номера, можно также захватить область — группу кода междугородней связи — для последующего использования.

Организация подстрок соответствия в группы весьма удобна. Но что еще удобнее, так это возможность назначения группам имен. Взгляните на следующий модифицированный пример:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
using System.Text.RegularExpressions;
public class EntryPoint
{
static void Main ( string[] args )  {
if( args.Length < 1 )  {
Console.WriteLine( "Вы должны предоставить строку." );
return;
}
// Создать регулярное выражение для поиска шаблона IP-адреса.
string pattern = @"(?<partl>[01]?\d\d?|2[0-4]\d|25[0-5])\." + @"(?<part2>[01]?\d\d?|2[0-4]\d|25[0-5])\." + б"(?<part3>[01]?\d\d?12[0-4]\d|25[0-5])\." + @"(?<part4>[01]?\d\d?|2[0-4]\d|25[0-5])";
Regex regex = new Regex ( pattern ) ;
Match match = regex.Match( args[0] );
while ( match.Success )  {
Console.WriteLine ( "IP-адрес найден в позиции {0} со " +
"значением {1}",
match.Index,
match.Value ) ;
Console.WriteLine ( "Группы:" );
Console.WriteLine( "\t4ac«Pb 1: {0}",
match.Groups["parti"] ) ;
Console.WriteLine( "\t4acTb 2: {0}",
match.Groups["part2"] ) ;
Console.WriteLine( "\t4ac*b 3: {0}",
match.Groups["part3"] ) ;
Console.WriteLine( "\t4acTb 4: {0}",
match.Groups["part4"] ) ;
match = match.NextMatch();

В этом варианте кода каждая часть захватывается в группу с некоторым именем, и при отправке результата на консоль обращение к группе осуществляется по имени через индексатор в GroupCollection, который возвращен методом Match. Groups, принимающим строковый аргумент.

Благодаря именованию групп, появилась возможность ссылаться на них внутри поиска. Например, при поиске точного повторения предыдущего соответствия можно обратиться к предыдущей группе с помощью того, что называется обратной ссылкой, включив \n<имя>, где имя — имя группы для обратной ссылки.

Например, рассмотрим следующий пример поиска IP-адресов, у которых все части совпадают:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System;
using System.Text.RegularExpressions;
public class EntryPoint
{
static void Main( string[] args )  {
if ( args.Length < 1 )  {
Console.WriteLine ( "Вы должны предоставить строку." );
return;
}
// Создать регулярное выражение для поиска шаблона IP-адреса,
string pattern = @"(?<partl>[01]?\d\d?|2[0-4]\d|25[0-5])\." + @"\k<partl>\." + @"\k<partl>\." + @"\k<partl>";
Regex regex = new Regex ( pattern ) ;
Match match = regex.Match ( args[0] );
while ( match.Success )  {
Console.WriteLine ( "IP-адрес найден в позиции {0} со " + "значением {1}", match.Index, match.Value );
match = match.NextMatch();
}

Ниже показан результат запуска этого кода с параметром “Мой IP-адрес выглядит как 123.123.123.123″:
IP-адрес найден в позиции 26 со значением 123.123.123.123

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100