Кратко съдържание



страница70/73
Дата21.07.2018
Размер9.03 Mb.
1   ...   65   66   67   68   69   70   71   72   73

Няколко прости примера


Както вече обяснихме, регулярните изрази сами по себе си са низове, които използваме, за да търсим съвпадения на символни последовател­ности с дефинирания шаблон. Да разгледаме няколко съвсем прости примера, които ще ни помогнат по-лесно да се ориентираме в основните възможности на регулярните изрази.

Лесен пример за начало


Следният низ е един прост регулярен израз:

пример номер [0-9]+

Този шаблон ще намери съвпадения с всички поднизове, които започват с фразата "пример номер", следвана от поне една десетична цифра.

Квадратните скоби в езика на регулярните изрази указват клас от символи – в случая това са всички символи в диапазона между 0 и 9. Знакът + ни казва, че предходният символ (или в случая целият клас символи [0-9]) трябва да се среща последователно 1 или повече пъти. Така низът "пример номер 987" ще бъде счетен за съвпадение с шаблона, както и низът "пример номер 05". Низът "пример номер" няма да е съвпадение, защото по шаблона трябва да има поне една цифра на края.

С този шаблон ние можем, разбира се, да търсим съвпадения и в по-дълъг текст. Да разгледаме например низа "Това е вашият пример номер 10". В този низ има подниз, който съвпада с шаблона и той се счита за съвпаднат по регулярния израз – това е поднизът "пример номер 10".

Търсене на телефонни номера


Да разгледаме друг пример:

(+359|0)88[0-9]{7}

С този израз можем да намерим съвпадения с номера на мобилни теле­фони в мрежата на М-Тел. Отново използваме символния клас за цифри [0-9], следван от модификатора за количество {7} – това означава, че трябва да има точно 7 повторения на символи от класа [0-9]. В началото имаме (+359|0), което означава, че номерът трябва да започва или с +359, или с 0. Символът | обозначава алтернативни възможности. Примери за номера, който съвпадат с шаблона, са "+359887675340" и "0888997621", но не и "188385953" (започва с 1), или "+3598890076" (има само пет цифри след "+35988").

Пример за регулярен израз в .NET


Преди да преминем към по-детайлното описание на езика на регулярните изрази, нека разгледаме и един цялостен пример за използване на такъв израз в .NET:

static void Main()

{

string text = "Няма скара, няма бира, няма какво да ям";



string pattern = @"\w*ира|скара|\w*ям\w*";

Match match = Regex.Match(text, pattern);

while (match.Success)

{

Console.WriteLine(



"Низ: \"{0}\" - начало {1}, дължина {2}",

match, match.Index, match.Length);

match = match.NextMatch();

}

}


Как работи примерът?


Регулярният израз, който се съдържа в низа pattern, търси за три алтернативни възможности:

  • подниз, завършващ на "ира" – това се сочи от частта "\w*ира", където \w* означава произволна последователност (може и с нулева дължина) от букви, цифри и знак за подчертаване.

  • подниз "скара".

  • подниз (отново от букви, цифри и знак за подчертаване), който съдържа подниза "ям".

Както виждаме, за търсенето на съвпадения се използват методите на класовете Regex и Match. Те ще бъдат разгледани подробно по-късно в темата. Изходът от горния пример е следният:


Езикът на регулярните изрази


Богатството на синтаксиса на регулярните изрази позволява голяма гъвка­вост при изграждането на шаблони. Пълните възможности на езика рядко се ползват в практиката, но за по-специфични задачи все пак може да се наложи и тяхното познаване. Ние ще разгледаме първо с по-основните и често използвани конструкции, а по-нататък в темата ще обясним и някои от по-интересните детайли на регулярните изрази.

В синтактичен план езикът на регулярните изрази се дели на две основни групи – литерали и метасимволи (символи със специално значение).


Литерали


Литералите са символи и поднизове в регулярния израз, които се въз­приемат от апарата за обработка буквално, в стандартния си смисъл. Литералите се използват, за да фиксираме частта от шаблона, която за­дължително трябва да присъства точно в посочения вид. Например в регу­лярния израз, съхраняван в променливата pattern, която разгледахме в примера по-горе, частите "ира", "скара" и "ям" са литерали – те се търсят в текста от машината на регулярните изрази (regex engine) точно в този си вид, в който ги виждаме написани.

Метасимволи


Метасимволите са група от символи, които имат специално значение в езика на регулярните изрази. С тяхна помощ реално се постига цялата функционалност и описателност на апарата, който разглеждаме. Метасим­волите, с които разполагаме, осигуряват достатъчно гъвкавост, за да можем да опишем практически почти всеки шаблон, който би могъл да ни трябва.

Символите, които се третират по специален начин от машината на регулярните изрази в зависимост от позицията си, са следните: [, ], |, *, ., +, ?, (, ), {, }, \, ^ и $. Най-често обаче терминът "метасимволи" се използва не за тях, а за специалните конструкции, които носят определен смисъл за шаблона и в които тези символи участват.

В примера, който разгледахме по-горе, метасимволи са "\w" и "*", както и "|". Вече обяснихме донякъде тяхното значение, а останалите специ­ални символи ще разгледаме малко по-нататък.

Escaping при регулярните изрази


Естествено, тъй като метасимволите се третират по нетривиален начин при парсването на регулярния израз, те не могат да се използват като литерали директно и не могат да се търсят като обикновени символи. Както и при повечето програмни езици, този проблем се избягва с помощта на escaping чрез символа \ (backslash). Поставен пред някой от специалните символи, които изброихме по-горе, този символ отменя особеното им значение и те се третират по обикновения начин. Например \* означава *, \+ означава + и т.н. Това важи разбира се и за самия символ \, т.е. ако искаме да го използваме като литерал, трябва да използваме \\.

Ще обърнем внимание, че някои от изброените по-горе метасимволи имат специално значение само на определени места в шаблона. Например сим­волът ], както и символите ) и } са метасимволи само ако преди тях в шаблона има незатворена съответната отваряща скоба. Ако се опитаме да ползваме escaping на тези символи в друг контекст, ще получим грешка, защото това обърква парсването.

Всъщност всички срещания на символа \, последван от символ, който не е разпознат като специална escaping последователност, водят до изключе­ние по време на изпълнението на програмата.

Други escaping последователности


Както при повечето езици за програмиране, в регулярните изрази може да се използват познатите последователности за обозначаване на специал­ните ASCII символи, за които няма видимо означение. Ще изброим някои от тях:

  • \n – нов ред (new line)

  • \r – връщане на каретката (carriage return)

  • \t – табулация (tab)

  • \a – звуков сигнал (bell)

  • \b – връщане назад (backspace)

Комбинацията \b, както ще видим по-нататък, всъщност има по-специално значение за синтаксиса на регулярните изрази. Ето защо можем да я използваме като backspace единствено в споменатата конструкция за клас от символи [] и в шаблоните за заместване, за които ще стане дума по-късно.

Escaping последователности за Unicode и ASCII кодове


Езикът на регулярните изрази дава възможност да се използват директно ASCII и Unicode кодове на символи за означението им в шаблона. Това става по три начина:

  • \XXX – символът \, последван от най-много три цифри, представя ASCII символ, въведен с осмичен код. Например \040 е интервал, а \081 – буквата A. Позволено е и даже се препоръчва да се използват водещи нули, за да се избягва двусмислие с подобната конструкция за обратни препратки, за която ще говорим по-късно.

  • \xXX – комбинацията \x, последвана от точно две цифри, обозна­чава ASCII символ в шестнайсетичен код. Например интервалът е \x20, а буквата A\x41.

  • \uXXXX – тази комбинация (с точно четири цифри) представя Unicode символен код също чрез шестнайсетични числа. В този формат символът за интервал се означава като \u0020, а буквата A – като \u0041. Символът ï, например, можем да означим с \u00EF.

Някои особености


Когато използваме escaping при регулярните изрази в .NET Framework, не трябва да забравяме, че се налага да се съобразяваме и с компилатора. Преди да се подадат на машината на регулярните изрази, низовете, които използваме за шаблони, първо се обработват от парсер, който има соб­ствени escaping последователности.

В езика C# символът \ се използва в низовете също за escaping. Трябва да се съобразяваме с този факт, защото можем да стигнем до нежелани резултати, ако не внимаваме. Да разгледаме шаблона "\w*", който както ще видим по-късно, най-общо означава произволна дума. Ако напишем този низ в нашия сорс код, ще получим грешка при компилация, защото компилаторът на C# не може да разпознае "\w" като коректна escaping последователност. Ето защо трябва да освободим символа \ от специал­ното му значение, като използваме escaping и за него – "\\w*". Сега вече след преминаването през парсера на C# компилатора този низ ще има вида "\w*", което е коректно за машината за регулярни изрази, която ще го обработи по време на изпълнение.

Какво трябва да направим, ако искаме да използваме \ като обикновен символ в израза (когато търсим последователност, в която той участва)? Тогава трябва да имаме "\\" в шаблона, например "c:\\windows". Но преди да се разчете като шаблон от машината за регулярни изрази, този низ ще мине през парсера по време на компилация и там двата символа backslash ще се редуцират до един по правилата за escaping в C#, при което ще получим в резултат "c:\windows". Тук обаче \w има значение на метасимвол и ще получим нежелан резултат. Затова в сорс кода трябва да имаме "c:\\\\windows" – т.е. четири повторения на \, за да намерим съв­падение с един такъв символ.

Използване на символа @


Както отбелязахме в темата за символните низове, в езика C# при поста­вянето на @ пред отварящите кавички на низа всички специални символи в него (освен кавичките) губят специалното си значе­ние. Това е много удобно при шаблоните за регулярни изрази и е препо­ръчително да се използва винаги, защото спестява проблемите, описани в горния абзац. Горните два примера можем да променим така:

string patternWord = @"\w+";

//Same as: patternWord = "\\w+";

string patternDir = @"c:\\windows";

//Same as: patternDir = "c:\\\\windows";



Използването на @ ни позволява да записваме низа във вида, в който той ще се прочете от машината за регулярните изрази (с малки изключения за кавичките). Това е доста удобно и е добре да го използваме.



Поделитесь с Вашими друзьями:
1   ...   65   66   67   68   69   70   71   72   73


База данных защищена авторским правом ©obuch.info 2019
отнасят до администрацията

    Начална страница