Регулярни изрази всеки знак, различен от дадения. Практическо въведение в регулярните изрази за начинаещи

Лесно и забавно въведение в теорията на регулярните изрази от уеб разработчика Джош Хокинс, Regex покрива всички основни неща, които един начинаещ трябва да знае.

Работили ли сте някога със струни? Да, да, със същите тези „масиви от знаци“, които всички познаваме и обичаме. Ако сте програмирали на нещо различно от чисто C, е безопасно да се предположи, че сте работили, и то повече от веднъж. Но какво ще стане, ако имате работа с много низове? Или с низове, които не са генерирани от вашата програма? Например, вие четете електронна поща, анализиране на аргументи на командния ред или четене на инструкции, написани от човек, и имате нужда от по-структуриран метод за работа с всичко това.

Разбира се, можете да повторите всяка дума или знак във всички редове. И код като този вероятно ще бъде доста лесен за разбиране. Но в широкомащабни приложения това може да бъде ненужно тромаво и твърде ресурсоемко.

Въведение. Редовен израз

Без да навлизаме в джунглата на дълбоката компютърна наука, нека дефинираме регулярен израз.

  • Регулярните изрази са правила, които описват някакъв формален език.
  • Регулярните изрази са вид формален език, който може да се обработва от държавна машина.

Има много други дефиниции на регулярни изрази, така че ако горното не е достатъчно, за да ви направи щастливи, можете да прекарате няколко минути в гугъл.

Въведение. Regex

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

  • Регулярните изрази от гледна точка на компютърните науки са правила, които обясняват формален език.
  • Регулярните изрази от гледна точка на езиците за програмиране са граматика, която изразява в по-голяма степен някои чувствителен към контекста език.

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

Научаване на писане на регулярен израз

Регулярните изрази се описват с две наклонени черти ( // ) и съответстват на низове, които съответстват на модела между тях. Например, /Здрасти/ съвпада с "Hi", така че можем да проверим дали някой низ отговаря на този модел.

Знаците в регулярните изрази се съпоставят в реда, в който са въведени. Така /Здравей свят/ отговаря на низа „Hello world“.

Можете да улесните търсенето на произволни думи, като добавите малко магия с регулярен израз: \w съвпада с всяка „дума“, съставена само от букви. Числата се идентифицират по същия принцип: .

Пример 1

Страхотно, сега можем да сравняваме низове или да проверяваме дали отговарят на определен модел. Какво следва? Могат ли регулярните изрази да изпълняват други функции?

Бъдете спокойни! Да кажем, че сме написали IRC чат бот, който реагира, ако някой напише „Josh“. Нашият бот сканира всяко съобщение, докато не намери съвпадение. След това ботът отговаря: „Уау, надявам се, че не говориш лошо за моя приятел Джош!“ („О, надявам се, че няма да говориш лошо за моя приятел Джош!“). Защото само роботите са приятели на Джош.

Нашият бот използва шаблон за сравняване на низове /Джош/ . В един момент някой на име Ели ще каже: „Ели: Джош, наистина ли имаш нужда от толкова много кофеин?“ Нашият бот ще наостри уши, ще открие съвпадение и ще даде своя неочакван отговор, който ще изплаши Ели достатъчно. Мисията е завършена! Или не?

Ами ако нашият бот беше по-умен? Ами ако той например се обърна към говорещия по име? Нещо като „Уау, надявам се, че не злословиш моя приятел Джош, Ели.“

Квантори (повтарящи се знаци)

0 или повече

Можем да направим това... Но първо трябва да разберем няколко неща. първо - квантификатори(за повтарящи се знаци). Може да се използва * за да посочите 0 или повече знака след. Например, /a*/ може да съответства на "aaaaaaa", както и на "". Да, чухте правилно: ще отговори на празен низ.

* служи за обозначаване на нещо незадължително, тъй като символът, на който съответства, изобщо не трябва да съществува. Но той може. И то повече от веднъж (теоретично безброй пъти).
Можете да обозначите „Джош“ с /Джош/ , но можем също да посочим „Jjjjjjjjjosh“ или „osh“ с шаблона /J*osh/ .

1 или повече

За обозначаване на един или повече знаци се използва + . Действа ефективно на същия принцип като * , с изключение на това, че съществуването на поне един символ вече не е задължително: той трябва да присъства понеедин.

Така че можем да зададем шаблона /J+osh/ низовете "Josh" или "Jjjjjjjjjosh", но не и "osh".

Метазнаци

Страхотно, вече сме си освободили ръцете в много отношения. Някой може да крещи "Jooooooosh" точно сега, ако вече е достатъчно ядосан...

Но какво ще стане, ако е толкова ядосан, че дори е ударил лицето си в клавиатурата няколко пъти? Как да обозначим „aaavyopshadlorvpt“, без да знаем предварително колко точен е носът му?
Като се използва метазнаци!

Метасимволите ви позволяват да посочите абсолютно ВСИЧКО. Синтаксисът им е . . (Да, точка. Само точка.). Обзалагаме се, че го използвате често, така че не се притеснявайте да го използвате, за да маркирате края на изречението.

Можете да зададете „Joooafhuaisggsh“ с израза /Джо+.*ш/ , комбинирайки придобити преди това знания за повтарящи се знаци и метазнаци. За да бъдем точни, този изразсъвпада с едно "J", едно или повече "o", нула или повече метазнаци и едно "s" и едно "h". Тези пет блока ни водят до това, което наричаме...

...групи герои

Групи знаци- това са символни блокове, в които последователността на компонентите е важна. Те се разглеждат като цяло. Използвайки * или + , вие всъщност указвате поредица от повтаряща се група от знаци, а не само последния знак.

Това е полезно да се разбира като самостоятелна техника, но придобива по-голяма функционалност, когато се комбинира с повтарящи се символи. Групите от знаци се определят с помощта на скоби (да, тези момчета).
Да кажем, че искаме да повторим "Jos", но не и "h". нещо като „JosJosJosJosJosh“. Това може да стане с израза /(Jos)+h/ . Просто, нали?

Но накрая... Връщайки се към първия ни пример, как да получим името на Али в нашия IRC чат от съобщението, което тя е изпратила?

Групи знаци могат също да служат за запомняне на поднизове. За да направят това, те обикновено правят нещо подобно \1 за определяне на първата посочена група.

Например, /(.+) \1/ - специален случай. Тук виждаме набор произволни символи, повторен един или повече пъти, интервал след него и след това повторение на същия набор отново. Така че такъв израз ще съответства на "abc abc", но не и на "abc def", въпреки че самото "def" съвпада (.*) .

Запомнянето на мачове е много мощно нещо и вероятно се свежда до полезна функциярегулярни изрази.

Пример 2

Фу... И накрая, можем да се върнем към примера с IRC чат бота. Нека приложим знанията си на практика.

Ако искаме да уловим името на подателя на съобщението, когато пише „Джош“, нашият израз ще изглежда така: /(\w+): .*Джош.*/ и можем да съхраним резултата в променлива на нашия език за програмиране за отговор.

Нека разгледаме нашия регулярен израз. Ето една или повече букви след " : ", 0 или повече знака, "Джош" и отново 0 или повече знака.

Забележка: /.*word.*/ е лесен начин за указване на низ, съдържащ „word“, който може или не може да съдържа други знаци.

В Python ще изглежда така:
внос повторно
pattern = re.compile(ur"(\w+): .*Josh.*") # Нашият регулярен израз
string = u"Eli: Джош иди премести прането си" # Нашият низ
matches = re.match(pattern, string) # Тествайте низа
who = matches.group(1) # Вземете кой е казал съобщението
печат (кой) # "Ели"
Забележете, че използвахме .group(1) точно като \1 . Това не е нищо ново, с изключение на използването на регулярни изрази в Python.

Начало и край

До този момент приемахме, че поднизовете, които търсим, могат да бъдат разположени навсякъде в низа. напр. /(Jos)+h/ съвпада с всеки низ, който съдържа "Jos-repeated-h" на всяко място.

Ами ако искаме низът да започва с този модел? Това може да се означи като /^(Jos)+h/ , Където ^ съответства на началото на реда. по същия начин $ маркира края на реда.

Сега, ако искаме да посочим низ, съдържащ само „Jos-repeating-h“, ще напишем /^(Jos)+h$/ .

Изброяване на изрази

Представете си, че пишете регулярен израз за рецепта за сандвич. Не знаете дали клиентът предпочита бял или черен хляб, но все пак трябва да изберете само един. Как да добавите възможност за избор към регулярен израз? Като се използва трансфери!

Те ви позволяват да зададете набори от възможни стойности за група знаци. Изглежда така: (бяло|пшеница) . В контекста на нашия пример за сандвич ще бъде приета една от опциите - или „бяло“, или „пшенично“.

За обозначаване на изброяването [квадратните скоби] се използват малко по-различно. Вместо целия низ, тук всеки знак е вариант. Това може да бъде полезно за сложни регулярни изрази, тъй като можете да замените един знак с по-сложен набор.

Модификатори

Говорихме за регулярен израз с /две наклонени черти/, нали? Знаем какво има между тях, но какво трябва да има отвън?

Неочакван обрат: нищо!

…наляво. Правилната страна, напротив, може да съдържа много, много полезни неща. Жалко, че не казахме нито дума за това толкова дълго!
Модификаторидефинирайте правилата, по които се прилагат регулярни изрази.

Ето списък на основните модификатори (от Regex101.com):

Модификатор Име Описание
ж глобален Всички мачове
м многоредов ^ и $ съответстват на началото и края на всеки ред
i нечувствителен Сравнение без значение за малки и големи букви
х удължен Интервалите и текстът след # се игнорират
х екстра \ с произволна буква, която няма специално значение, връща грешка
с една линия Игнорира новите редове
u уникод Шаблонните низове се обработват като UTF-16
U неалчен По подразбиране регулярният израз използва мързеливо количествено определяне. Модификаторът U прави количественото определяне алчно
А закотвен Моделът е принуден да ^
Дж дубликат Позволява дублирани имена на подмодели

За по-голяма яснота всички предишни примери са чувствителни към главни и малки букви. Това означава, че ако замените поне един малка буквакъм капитал или обратно, линията вече няма да отговаря на модела. Но можете да го направите нечувствителен към главни и малки букви, като използвате модификатор i .

Да предположим, че Ели се ядоса толкова, че започна да бомбардира чата със съобщения с БУКВИ от РАЗЛИЧНИ РЕГИСТРИ. Това не ни плаши, защото вече съм тук! Можем лесно да определим гневния израз „Мразя да живея с JOSH!!!“ с модела /мразя да живея с Джош!+/i . Нашият регулярен израз вече е по-лесен за четене и много по-мощен и полезен. невероятно!

Можете сами да играете с различни модификатори. Според мен като цяло ще се възползвате най-много от igm .

Какво следва?

Надявам се, че тази статия ми е позволила да погледна по различен начин на работата с низове и да я направя по-разумна. Ние само надраскахме повърхността, но вече сте научили как да използвате регулярен израз за решаване на някои проблеми.

Има много знаци и техните комбинации, използвани в регулярни изрази. Обикновено ще се натъкнете на тях, докато изследвате Препълване на стека, но значението на някои може да се познае от предишни примери (напр. - символ за нов ред). Основата е положена, но има още много да се учи.

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

След точката

Тази статия е превод на ръководството на Джош Хокинс. Джош е страстен уеб разработчик от Алабама. Започва да програмира на деветгодишна възраст, като се фокусира върху видеоигри, десктоп и други мобилни приложения. Въпреки това, по време на стаж през 2015 г., Джош открива уеб разработката и навлиза в света на отворения код, свързан с тази област.

Модификатори

Символът минус (-), поставен до модификатор (с изключение на U), създава неговото отрицание.

Специални символи

АналоговОписание
() подмодел, вложен израз
заместващ знак
(a,b) брой повторения от "a" до "b"
| логическо "или", в случай на използване на алтернативи с един знак
\ escape специален знак
. всеки знак с изключение на подаване на ред
десетична цифра
[^\d]всеки знак, различен от десетична цифра
\f край (край на страница)
ред превод
\pL буква в UTF-8 кодиране при използване на модификатора u
\r връщане на каретка
[\t\v\r\n\f]космически характер
[^\s]произволен знак с изключение на мигащия
\T табулиране
\w всяка цифра, буква или подчертаване
\W[^\w]всеки знак, различен от цифра, буква или долна черта
\v вертикален раздел

Специални знаци в клас знаци

Позиция в низ

ПримерКореспонденцияОписание
^ ^aааа аааначало на реда
$ $ааа аа а край на реда
\A\Aaааа ааа
ааа ааа
началото на текста
\za\zааа ааа
ааа аа а
край на текста
\ba\b
\ba
аа ааа а
ааа ааа
граница на думата, изявление: предишният знак е словесен, но следващият не е, или обратното
\Ba\Bа аа а аабез граница на думите
\G\GaааааааПредишно успешно търсене, търсенето спря на 4-та позиция - където a
Изтеглете в PDF, PNG.

Котви

Котвите в регулярните изрази показват началото или края на нещо. Например редове или думи. Те са представени с определени символи. Например модел, съответстващ на низ, започващ с число, ще изглежда така:

Тук символът ^ обозначава началото на реда. Без него моделът ще съответства на всеки низ, съдържащ цифра.

Класове на знаци

Класовете знаци в регулярните изрази съответстват на определен набор от знаци наведнъж. Например \d съвпада с всяко число от 0 до 9 включително, \w съвпада с букви и цифри, а \W съвпада с всички знаци, различни от букви и цифри. Моделът, идентифициращ букви, цифри и интервал, изглежда така:

POSIX

POSIX е сравнително ново допълнение към семейството на регулярните изрази. Идеята, както при класовете знаци, е да се използват преки пътища, които представляват някаква група знаци.

Изявления

Почти всеки има проблеми с разбирането на утвържденията в началото, но когато се запознаете по-добре с тях, ще откриете, че ги използвате доста често. Твърденията предоставят начин да се каже: „Искам да намеря всяка дума в този документ, която включва буквата „q“ и не е последвана от „werty“.

[^\s]*q(?!werty)[^\s]*

Кодът по-горе започва с търсене на знаци, различни от интервал ([^\s]*), последвани от q. След това анализаторът достига до прогнозно твърдение. Това автоматично прави предходния елемент (символ, група или клас на знаци) условен — той ще съвпада с модела само ако твърдението е вярно. В нашия случай твърдението е отрицателно (?!), тоест ще е вярно, ако не се намери търсеното в него.

И така, анализаторът проверява следващите няколко знака спрямо предложения модел (werty). Ако бъдат открити, тогава твърдението е невярно, което означава, че символът q ще бъде „игнориран“, тоест няма да съответства на шаблона. Ако werty не е намерено, тогава твърдението е вярно и всичко е наред с q. След това търсенето продължава за знаци, различни от интервал ([^\s]*).

Квантори

Кванторите ви позволяват да дефинирате част от модел, която трябва да се повтори няколко пъти подред. Например, ако искате да разберете дали даден документ съдържа низ от 10 до 20 (включително) букви "а", тогава можете да използвате този модел:

A(10,20)

По подразбиране кванторите са „алчни“. Следователно кванторът +, означаващ „един или повече пъти“, ще съответства на максималната възможна стойност. Понякога това създава проблеми и тогава можете да кажете на квантификатора да спре да бъде алчен (да стане „мързелив“), като използвате специален модификатор. Вижте този код:

".*"

Този шаблон съответства на текста, ограден в двойни кавички. Вашият изходен ред обаче може да бъде нещо подобно:

Здравей свят

Горният шаблон ще намери следния подниз в този ред:

"helloworld.htm" title="Здравей свят" !}

Той се оказа твърде алчен, пленяващ най-голямото парчетекст, който би могъл.

".*?"

Този модел съвпада и с всички знаци, затворени в двойни кавички. Но мързеливата версия (забелязахте ли модификатора?) търси най-малкото възможно срещане и следователно ще намери всеки подниз в двойни кавички поотделно:

"helloworld.htm" "Здравей свят"

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

Регулярните изрази използват определени знаци за представяне на различни части от шаблон. Въпреки това, възниква проблем, ако трябва да намерите един от тези знаци в низ, точно като обикновен знак. Точка, например, в регулярен израз означава „всеки знак, различен от прекъсване на ред“. Ако трябва да намерите точка в низ, не можете просто да използвате " » като шаблон - това ще доведе до намиране на почти всичко. И така, трябва да кажете на анализатора, че тази точка трябва да се счита за обикновена точка, а не за "който и да е знак". Това става с помощта на знак за бягство.

Екраниращ знак, предшестващ символ като точка, кара анализатора да игнорира неговата функция и да го третира като нормален знак. Има няколко знака, които изискват такова екраниране в повечето шаблони и езици. Можете да ги намерите в долния десен ъгъл на листа за измама („Мета символи“).

Моделът за намиране на точка е:

\.

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

Специални екраниращи знаци в регулярни изрази

Замяна на низове

Заместването на низове е описано подробно в следващия параграф, „Групи и диапазони“, но тук трябва да се спомене съществуването на „пасивни“ групи. Това са групи, които се игнорират по време на заместването, което е много полезно, ако искате да използвате условие "или" в шаблон, но не искате тази група да участва в заместването.

Групи и диапазони

Групите и диапазоните са много, много полезни. Вероятно е по-лесно да започнете с диапазони. Те ви позволяват да зададете набор от подходящи знаци. Например, за да проверите дали даден низ съдържа шестнадесетични цифри (от 0 до 9 и от A до F), бихте използвали следния диапазон:

За да проверите обратното, използвайте отрицателен диапазон, който в нашия случай отговаря на всеки знак с изключение на числа от 0 до 9 и букви от A до F:

[^A-Fa-f0-9]

Групите се използват най-често, когато е необходимо условие "или" в шаблон; когато трябва да се обърнете към част от шаблон от друга част от него; а също и при заместване на низове.

Използването на "или" е много просто: следният модел търси "ab" или "bc":

Ако в регулярен израз е необходимо да се препрати към някоя от предходните групи, трябва да използвате \n, където вместо n заместете числото желаната група. Може да искате модел, който съвпада с буквите "aaa" или "bbb", последвани от число и след това същите три букви. Този модел се прилага с помощта на групи:

(aaa|bbb)+\1

Първата част от модела търси "aaa" или "bbb", комбинирайки намерените букви в група. Това е последвано от търсене на една или повече цифри (+) и накрая \1. последната частшаблонът препраща към първата група и търси същото. Той търси съвпадение с текста, който вече е намерен от първата част на шаблона, а не съвпадение с него. Така че "aaa123bbb" няма да удовлетвори горния модел, тъй като \1 ще търси "aaa" след числото.

Един от най полезни инструментив регулярните изрази е заместване на низ. Когато замествате текст, можете да препратите към намерената група, като използвате $n. Да приемем, че искате да маркирате всички думи „wish“ в текста с удебелен шрифт. За да направите това, трябва да използвате функция за замяна на регулярен израз, която може да изглежда така:

Замяна (образец, замяна, тема)

Първият параметър ще бъде нещо като този шаблон (може да ви трябват няколко допълнителни знациза тази специфична функция):

([^A-Za-z0-9])(желание)([^A-Za-z0-9])

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

$1$2$3

Той ще замени целия низ, намерен с помощта на шаблона. Започваме да заместваме с първия намерен знак (това не е буква или цифра), отбелязвайки го $1. Без това просто бихме премахнали този знак от текста. Същото важи и за края на смяната ($3). В средата добавихме HTML тагза получер (разбира се, можете да използвате CSS или ), разпределяйки им втората група, намерена с помощта на шаблона ($2).

Ако някога ви се е налагало да работите с командна линия, вероятно сте използвали маски за имена на файлове. Например, за да изтриете всички файлове в текущата директория, които започват с буквата „d“, можете да напишете rm d*.

Регулярните изрази са подобен, но много по-мощен инструмент за намиране на низове, тестването им спрямо шаблон и друга подобна работа. Английското име на този инструмент е Регулярни изразиили просто RegExp. Строго погледнато, регулярните изрази са специален езикза описване на низови модели.

Изпълнението на този инструмент варира в зависимост от различни езиципрограмиране, макар и не много. В тази статия ще се съсредоточим основно върху внедряването на съвместими с Perl регулярни изрази.

Основи на синтаксиса

Преди всичко си струва да се отбележи, че всеки низ сам по себе си е регулярен израз. Така че изразът „Хаха“ очевидно ще съответства на реда „Хаха“ и само това. Регулярните изрази са чувствителни към малки и големи букви, така че низът "хаха" (малки букви) вече няма да съответства на израза по-горе.

Тук обаче трябва да внимавате - като всеки език, регулярните изрази имат специални знаци, които трябва да бъдат екранирани. Ето техния списък:. ^ $ * + ? ( ) \ | (). Извършва се екраниране по обичайния начин- добавяне на \ преди специалния знак.

Набор от знаци

Да предположим, че искаме да намерим всички междуметия в текст, които показват смях. Hakha просто няма да ни подхожда - в крайна сметка „Hehe“, „Hoho“ и „Hihi“ няма да попаднат под него. И проблемът с главния регистър на буквите трябва да се реши някак.

Тук наборите ще ни дойдат на помощ - вместо да посочваме конкретен знак, можем да запишем цял списък и ако в проверявания ред определено местоположениеще бъде някой от изброените символи, низът ще се счита за подходящ. Пише се на комплекти квадратни скоби- моделът ще съвпадне с някой от символите „a“, „b“, „c“ или „d“.

Вътрешен комплект b ОПовечето специални символи не трябва да бъдат екранирани, но използването на \ пред тях няма да се счита за грешка. Все още е необходимо да се екранират знаците „\“ и „^“, и за предпочитане „]“ (това означава всеки от знаците „]“ или „[“, докато [x] е изключително последователността „[ х]"). Привидно необичайното поведение на регулярните изрази със знака "]" всъщност се определя от добре известни правила, но е много по-лесно просто да избягате от този знак, отколкото да ги запомните. В допълнение, символът „-“ трябва да бъде екраниран;

Ако напишете символа ^ непосредствено след [, наборът ще придобие обратното значение - всеки символ, различен от посочените, ще се счита за подходящ. По този начин моделът [^xyz] съвпада с всеки знак с изключение на “x”, “y” или “z”.

И така, използвайки този инструментв нашия случай, ако напишем [Xx][aoie]x[aoie], тогава всеки от редовете „Хаха“, „хехе“, „хихи“ и дори „Хохо“ ще съвпадне с шаблона.

Предварително дефинирани класове символи

За някои набори, които се използват доста често, има специални шаблони. И така, за да се опише всеки знак за празно пространство (интервал, табулация, нов ред) се използва \s, за числа - \d, за латински символи, цифри и долна черта "_" - \w.

Ако изобщо е необходимо да се опише някакъв знак, за това се използва точка. . Ако определени класовепишете с главна буква (\S, \D, \W), тогава те ще променят значението си на обратното - всеки знак, който не е интервал, всеки знак, който не е число, и всеки знак, различен от латинската азбука, цифри или подчертаване, съответно.

Освен това, използвайки регулярни изрази, е възможно да проверите позицията на ред спрямо останалата част от текста. Изразът \b обозначава граница на думата, \B е граница без дума, ^ е началото на текста и $ е краят. И така, според шаблона \bJava\b, първите 4 знака ще бъдат намерени в реда „Java и JavaScript“, а според шаблона \bJava\B ще бъдат намерени 10-ти до 13-ти знак (като част от думата „JavaScript“).

Диапазони

Може да се наложи да посочите набор, който съдържа букви, например от "b" до "f". Вместо да пишете [bvgdezziklmnoprstuf], можете да използвате механизма за диапазон и да пишете [b-f] . По този начин моделът x съответства на низа „xA6“, но не съответства на „xb9“ (първо, поради факта, че само главни букви, второ, поради факта, че 9 не е включено в диапазона 0-8).

Механизмът за обхват е особено подходящ за руския език, тъй като за него няма конструкция, подобна на \w. За да обозначите всички букви от руската азбука, можете да използвате модела [а-яА-ЯеО] . Моля, обърнете внимание, че буквата „е“ не е включена в общия набор от букви и трябва да бъде посочена отделно.

Квантори (указващи броя на повторенията)

Да се ​​върнем към нашия пример. Ами ако „смеещото се“ междуметие има повече от една гласна между х-овете, като „Хаахаааа“? Нашият стар редовен сезон вече няма да може да ни помогне. Тук ще трябва да използваме квантори.

Обърнете внимание, че кванторът се отнася само за знака, който стои преди него.

Някои често използвани конструкции са получили специални обозначения в езика на регулярните изрази:

И така, с помощта на квантори, можем да подобрим нашия модел за междуметия до [Xx][aoeee]+x[aoeee]* и той ще може да разпознава низовете „Хааха“, „хеееееех“ и „Хеехи“.

Мързеливо количествено определяне

Да предположим, че сме изправени пред задачата да намерим всички HTML тагове в низ

Tproger- моя скъпауебсайт за програмиране!

Очевидното решение<.*>тук няма да работи - ще намери целия низ, защото започва с и завършва с абзац таг. Тоест съдържанието на тага ще се счита за низ

P> Tproger- моя скъпауебсайт за програмиране!

Това се случва поради факта, че по подразбиране кванторът работи по т.нар. алченалгоритъм - опитва се да върне възможно най-дългия низ, който отговаря на условието. Има два начина за решаване на проблема. Първият е да използвате израза<[^>]*> , което ще забрани правото ъглова скоба. Второто е да обявим квантора не алчен, а мързелив. Това става ли чрез добавяне отдясно на квантора на знаците? . Тези. за търсене на всички тагове, изразът ще се превърне в<.*?> .

Ревниво количествено определяне

Понякога, за да увеличите скоростта на търсене (особено в случаите, когато низът не съответства на регулярния израз), можете да предотвратите връщането на алгоритъма към предишни стъпкитърсене, за да намерите възможни съвпадения за останалата част от регулярния израз. Нарича се ревнивколичествено определяне. Кванторът се прави ревнив чрез добавяне на символ + вдясно. Друга употреба на ревниво количествено определяне е да се изключат нежелани съвпадения. Така моделът ab*+a в низа “ababa” ще съответства само на първите три знака, но не и на символите от третия до петия, т.к. символът "а", който е на трета позиция, вече е използван за първия резултат.

Групи скоби

За нашия шаблон за „смеещо се“ междуметие единственото малко нещо, което остава, е да вземем предвид, че буквата „x“ може да се появи повече от веднъж, например „Хахахахаахаахоооо“, и дори може да завършва с буквата „x“. Вероятно трябва да използваме групов квантор [aioe]+x тук, но ако просто напишем [aoie]x+, кванторът + ще се приложи само към знака "x", а не към целия израз. За да се коригира това, трябва да се вземе предвид изразът кръгли скоби: ([aioe]х)+ .

Така нашият израз се превръща в [Хх]([аое]х?)+ - първо има главна или малка буква “x”, а след това произволен ненулев брой гласни, които (евентуално, но не задължително) се разпръскват с една малка буква „x“. Този израз обаче решава проблема само частично - този израз ще включва и реплики като например „хихахе“ - някой може да се смее така, но предположението е много съмнително. Очевидно можем да използваме набор от всички гласни само веднъж и тогава трябва по някакъв начин да разчитаме на резултата от първото търсене. Но как?…

Запомняне на резултата от търсенето по група (обратна връзка)

Оказва се, че резултатът от търсенето на група скоби се записва в отделна клетка от паметта, която може да бъде достъпна за използване в следващите части на регулярния израз. Връщайки се към задачата за намиране на HTML тагове на страница, може да се наложи не само да намерим таговете, но и да открием името им. Регулярният израз може да ни помогне с това<(.*?)> .

Tproger- моя скъпауебсайт за програмиране!

Резултат от търсенето за всички регулярни изрази: "

», « », «», « », «», «

».
Резултат от търсенето за първата група: “p”, “b”, “/b”, “i”, “/i”, “/i”, “/p”.

Резултатът от търсенето по група може да бъде препратен с помощта на израза \n, където n е число от 1 до 9. Например изразът (\w)(\w)\1\2 съответства на низовете „aaaa“, „abab “, но не съвпада с „ aabb.

Ако израз е поставен в скоби само за да се приложи квантификатор към него (няма планове за запомняне на резултата от търсенето за тази група), тогава веднага трябва да се добави първата скоба?:, например (?:+\w) .

Използвайки този механизъм, можем да пренапишем нашия израз във формата [Xx]([aoie])x?(?:\1x?)* .

Трансфер

За да проверите дали даден низ отговаря на поне един от шаблоните, можете да използвате аналог на булевия оператор OR, който се записва със символа | . По този начин моделът Anna|Loneliness включва съответно линиите „Anna“ и „Loneliness“. Особено удобно е да се използват изброявания в групи със скоби. Така например (?:a|b|c|d) е напълно еквивалентен (in в такъв случайвторият вариант е за предпочитане поради производителност и четливост).

Използвайки този оператор, можем да добавим към нашия регулярен израз за намиране на междуметия способността да разпознаваме смях като „Ahahaah“ – единствената усмивка, която започва с гласна: [Xx]([aoie])x?(?:\1x?) *|[ Aa]h?(?:ah?)+

Полезни услуги

Можете да практикувате и/или да тествате своя регулярен израз върху някакъв текст, без да пишете код, като използвате услуги като RegExr, Regexpal или Regex101. Последният освен това дава кратки обяснения за това как работи обикновената система.

Можете да разберете как работи регулярният израз, който идва в ръцете ви, като използвате услугата

Какво представляват регулярните изрази?

Ако някога сте работили с командния ред, вероятно сте използвали маски за имена на файлове. Например, за да изтриете всички файлове в текущата директория, които започват с буквата "d", можете да напишете

Регулярните изрази са подобен, но много по-мощен инструмент за намиране на низове, тестването им спрямо шаблон и друга подобна работа. Английското име на този инструмент е Регулярни изразиили просто RegExp. Строго погледнато, регулярните изрази са специален език за описание на низови модели.

Изпълнението на този инструмент варира в различните езици за програмиране, макар и не много. В тази статия ще се съсредоточим основно върху внедряването на съвместими с Perl регулярни изрази.

Основи на синтаксиса

Преди всичко си струва да се отбележи, че всеки низ сам по себе си е регулярен израз. И така, изразът

Хаха очевидно ще съответства на низа „Хаха“ и само това. Регулярните изрази са чувствителни към малки и големи букви, така че низът "хаха" (малки букви) вече няма да съответства на израза по-горе.

Тук обаче трябва да внимавате - като всеки език, регулярните изрази имат специални знаци, които трябва да бъдат екранирани. Ето техния списък:

. ^ $ * + ? ( ) \ | (). Ескейпирането става по обичайния начин - добавяне на \ преди специалния знак.

Набор от знаци

Да предположим, че искаме да намерим всички междуметия в текст, които показват смях. Просто

Хаха няма да ни подхожда - в крайна сметка „Хехе“, „Хохо“ и „Хихи“ няма да попаднат под него. И проблемът с главния регистър на буквите трябва да се реши някак.

Тук на помощ ще ни дойдат набори – вместо да посочваме конкретен символ, можем да напишем цял списък и ако някой от изброените знаци се появи на посоченото място в низа, който се изследва, низът ще се счита за подходящ. Комплектите се изписват в квадратни скоби - модел

Ще съвпада с всеки от знаците "a", "b", "c" или "d".

Вътрешен комплект b ОПовечето специални знаци не се нуждаят от екраниране, а от използване

\ пред тях няма да се счита за грешка. Все още е необходимо да се екранират знаците „\“ и „^“, и за предпочитане „]“ (това означава всеки от знаците „]“ или „[“, докато [x] е изключително последователността „[ х]"). Привидно необичайното поведение на регулярните изрази със знака "]" всъщност се определя от добре известни правила, но е много по-лесно просто да избягате от този знак, отколкото да ги запомните. В допълнение, символът „-“ трябва да бъде екраниран;

Ако веднага след

[запишете символа ^, тогава наборът ще придобие противоположно значение - всеки символ, различен от посочените, ще се счита за подходящ. По този начин моделът [^xyz] съвпада с всеки знак с изключение на “x”, “y” или “z”.

И така, прилагайки този инструмент към нашия случай, ако пишем

[Xx][aoie]x[aoie] , тогава всеки от редовете „Ха-ха“, „хе-хе“, „хихи“ и дори „Хохо“ ще съответства на шаблона.

Предварително дефинирани класове символи

За някои набори, които се използват доста често, има специални шаблони. И така, за да опишете всеки знак за празно пространство (интервал, раздел, прекъсване на ред), използвайте

\s , за цифри - \d , за латински букви, цифри и долна черта "_" - \w .

Ако изобщо е необходимо да се опише някакъв знак, за това се използва точка -

Ако посочените класове са написани с главна буква (\S, \D, \W), тогава те ще променят значението си на обратното - всеки знак, който не е празно пространство, всеки знак, който не е число, и всеки знак, различен от Латинска азбука, съответно цифри или долна черта.

Също така, използвайки регулярни изрази, е възможно да проверите позицията на ред спрямо останалата част от текста. Изразяване

\b обозначава граница на думата, \B е граница без дума, ^ е началото на текста и $ е краят. И така, според шаблона \bJava\b, първите 4 знака ще бъдат намерени в реда „Java и JavaScript“, а според шаблона \bJava\B ще бъдат намерени 10-ти до 13-ти знак (като част от думата „JavaScript“).

Диапазони

Може да се наложи да посочите набор, който съдържа букви, например от "b" до "f". Вместо да пиша

[bvgdezziklmnoprstuf] можете да използвате механизма за обхват и да напишете [b-f] . И така, моделът x съвпада с низа „xA6“, но не съвпада с „xb9“ (първо, поради факта, че в диапазона са посочени само главни букви, и второ, поради факта, че 9 не е включено в интервал 0 -8).

Механизмът на диапазоните е особено подходящ за руския език, тъй като за него няма подобна конструкция

\w . За да обозначите всички букви от руската азбука, можете да използвате модела [а-яА-ЯеО] . Моля, обърнете внимание, че буквата „е“ не е включена в общия набор от букви и трябва да бъде посочена отделно.

Квантори (указващи броя на повторенията)

Да се ​​върнем към нашия пример. Ами ако „смеещото се“ междуметие има повече от една гласна между х-овете, като „Хаахаааа“? Нашият стар редовен сезон вече няма да може да ни помогне. Тук ще трябва да използваме квантори.

Обърнете внимание, че кванторът се отнася само за знака, който стои преди него.

Някои често използвани конструкции са получили специални обозначения в езика на регулярните изрази:

Така че с помощта на квантори можем да подобрим нашия модел за междуметия

[Xx][aoeee]+x[aoeee]* и ще може да разпознава редовете "Haaha", "heeeeeh" и "Hihii".

Мързеливо количествено определяне

Да предположим, че сме изправени пред задачата да намерим всички HTML тагове в низ

Tproger- моя скъпауебсайт за програмиране!

Очевидното решение

<.*>тук няма да работи - ще намери целия низ, защото започва с и завършва с абзац таг. Тоест съдържанието на тага ще се счита за низ p> Tproger- моя скъпауебсайт за програмиране!

Това се случва поради факта, че по подразбиране кванторът работи по т.нар. алченалгоритъм - опитва се да върне възможно най-дългия низ, който отговаря на условието. Има два начина за решаване на проблема. Първият е да използвате израза

<[^>]*> , което ще попречи на дясната ъглова скоба да се счита за съдържание на тага. Второто е да обявим квантора не алчен, а мързелив. Това става ли чрез добавяне отдясно на квантора на знаците? . Тези. за търсене на всички тагове, изразът ще се превърне в<.*?> .

Ревниво количествено определяне

Понякога, за да увеличите скоростта на търсене (особено в случаите, когато низът не съвпада с регулярния израз), можете да предотвратите връщането на алгоритъма към предишни стъпки на търсене, за да намери възможни съвпадения за останалата част от регулярния израз. Нарича се ревнивколичествено определяне. Кванторът се прави ревнив чрез добавяне на символа вдясно от него

Друга употреба на ревниво количествено определяне е да се изключат нежелани съвпадения. Така моделът ab*+a в низа “ababa” ще съответства само на първите три знака, но не и на символите от третия до петия, т.к. символът "а", който е на трета позиция, вече е използван за първия резултат.

Групи скоби

За нашия шаблон за „смеещо се“ междуметие единственото малко нещо, което остава, е да вземем предвид, че буквата „x“ може да се появи повече от веднъж, например „Хахахахаахаахоооо“, и дори може да завършва с буквата „x“. Вероятно трябва да използвате групов квантор тук

[aioe]+x, но ако просто напишем [aioe]x+, тогава кванторът + ще се приложи само към знака "x", а не към целия израз. За да коригирате това, изразът трябва да бъде поставен в скоби: ([aioe]x)+ .

Така нашият израз става

[Xx]([aioe]x?)+ - първо има главна или малка буква “x”, а след това произволен ненулев брой гласни, които (евентуално, но не задължително) са разпръснати с една малка буква “x” . Този израз обаче решава проблема само частично - този израз ще включва и реплики като например „хихахе“ - някой може да се смее така, но предположението е много съмнително. Очевидно можем да използваме набор от всички гласни само веднъж и тогава трябва по някакъв начин да разчитаме на резултата от първото търсене. Но как?…

Запомняне на резултата от търсенето по група (обратна връзка)

Оказва се, че резултатът от търсенето на група скоби се записва в отделна клетка от паметта, която може да бъде достъпна за използване в следващите части на регулярния израз. Връщайки се към задачата за намиране на HTML тагове на страница, може да се наложи не само да намерим таговете, но и да открием името им. Регулярният израз може да ни помогне с това

<(.*?)> .

Tproger- моя скъпауебсайт за програмиране!

Резултат от търсенето за всички регулярни изрази: "

», « », «», « », «», «

».
Резултат от търсенето за първата група: “p”, “b”, “/b”, “i”, “/i”, “/i”, “/p”.

Резултатът от групово търсене може да бъде цитиран с помощта на израза

\n , където n е число от 1 до 9. Например изразът (\w)(\w)\1\2 съвпада с низовете „aaaa“, „abab“, но не съвпада с „aabb“.

Ако израз е поставен в скоби само за да се приложи квантификатор към него (няма планове за запомняне на резултата от търсенето за тази група), тогава първата скоба трябва да се добави веднага

?: , например (?:+\w) .

Използвайки този механизъм, можем да пренапишем нашия израз във формата

[Xx]([aoie])x?(?:\1x?)* .

Трансфер

За да проверите дали даден низ отговаря на поне един от шаблоните, можете да използвате аналог на булевия оператор ИЛИ, който се записва със символа

| . По този начин моделът Anna|Loneliness включва съответно линиите „Anna“ и „Loneliness“. Особено удобно е да се използват изброявания в групи със скоби. Така например (?:a|b|c|d) е напълно еквивалентен (в този случай втората опция е за предпочитане поради производителност и четливост).

Използвайки този оператор, можем да добавим към нашия регулярен израз за намиране на междуметия способността да разпознаваме смях като "Ахахаах" - единствената усмивка, която започва с гласна:

[Xx]([aoie])x?(?:\1x?)*|[Aa]x?(?:ah?)+

Полезни услуги

Можете да практикувате и/или да тествате своя регулярен израз върху някакъв текст, без да пишете код, като използвате услуги като RegExr, Regexpal или Regex101. Последният освен това дава кратки обяснения за това как работи обикновената система.

Можете да разберете как работи регулярен израз, който попада във вашите ръце, като използвате услугата Regexper - тя може да изгради разбираеми диаграми, използвайки регулярен израз.

RegExp Builder - визуален конструктор JavaScript функцииза работа с регулярни изрази.

0

0

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

На пръв поглед регулярните изрази изглеждат страшни (добре, на втори поглед изглеждат още по-страшни ;)).

Горещо ви препоръчвам да „играете“ с демонстрационната програма за Windows REStudio, доставена в комплекта за разпространение - това ще ви позволи да разберете по-добре принципа на регулярните изрази и да отстраните грешките в собствените си изрази. TestRExp включва и много примерни изрази.

По-долу е дадено описание на подмножество от синтаксис на регулярен израз, който работи в почти всички реализации и се поддържа от моята библиотека Delphi, която е включена като стандарт в Lazarus (Free Pascal).

Нека започнем нашето въведение в регулярните изрази!

Просто сравнение

Всеки знак съвпада със себе си, освен ако не принадлежи към специалните метасимволи, описани по-долу.

Последователността от символи съвпада със същата последователност във входния низ, така че шаблонът bluh ще съответства на подниза bluh във входния низ. Дотук всичко е просто, нали?

Ако метасимволите или екраниращите последователности трябва да се третират като обикновени знаци, те трябва да бъдат предшествани от символ \, например, метасимволът ^ обикновено съвпада с началото на редовете, но ако е написан като \^, той ще съвпада със знака ^, \ \ съвпада с \ и т.н.

Примери:

foobar намира 'foobar' \^FooBarPtr намира '^FooBarPtr'

Ескейп последователности

Всеки знак може да бъде указан с помощта на последователност за изход, точно както се прави в C или Perl: \n означава началото на ред, \t означава раздел и т.н. Като цяло \xnn , където nn е последователност шестнадесетични цифри, означава знак с ASCII код nn. Ако трябва да зададете двубайтов (Unicode) знак, използвайте формата \x(nnnn) , където nnnn е една или повече шестнадесетични цифри.

\xnn знак s шестнадесетичен код nn \x(nnnn) знак с шестнадесетичен код nnnn (повече от един байт може да бъде указан само в (tregexpr_interface.html#unicode) режим)| \t раздел (HT/TAB), можете също \x09 \n нова линия(NL), можете също \x0a \r връщане на каретка (CR), можете също \x0d| \f превод на формат (FF), можете също да \x0c| \a разговор (БЕЛ), можете също \x07| \e escape (ESC), също \x1b|

Примери:

foo\x20bar намира 'foo bar' (обърнете внимание на интервала в средата) \tfoobar намира 'foobar', предшествано от раздел

Списъци със символи

Можете да дефинирате списък, като оградите знаците в . Списъкът ще съответства на всеки един символ, посочен в него.

Ако първият знак от списъка (непосредствено след [) е ^, тогава такъв списък съответства на всеки знак, който не е изброен в списъка.

Примери:

foobr намира 'foobar', 'foober' и т.н. но не и „foobbr“, „foobcr“ и т.н. foob[^aeiou]r намира 'foobbr', 'foobcr' и т.н., но не и 'foobar', 'foober' и т.н.

В рамките на списък знакът - може да се използва за определяне на диапазони от знаци, например a-z представлява всички знаци между a и z включително.

Ако трябва да включите самия символ в списъка, поставете го в началото или края на списъка или го предшествайте с \ . Ако трябва да включите знака ] в списъка, поставете го в самото начало или го предшествайте с \ .

Примери:

[-az] "a", "z" и "-" "a", "z" и "-" "a", "z" и "-" всички 26 малки латински буквиот "a" до "z" [\n-\x0D] #10, #11, #12, #13. [\d-t] цифра, "-" или "t". -a] символ от диапазона "]".."a".

Метазнаци

Метасимволите са специални знаци, които са най-важната концепция в регулярните изрази. Има няколко групи метазнаци.

Метасимволи - разделители на редове

^ начало на ред $ край на ред \A начало на текст \Z край на текст. произволен знак в низа

Примери:

^foobar намира "foobar" само ако е в началото на реда foobar$ намира "foobar" само ако е в края на реда ^foobar$ намира "foobar" само ако това е единствената дума в реда foob .r намира "foobar", "foobbr", "foob1r" и т.н.

Метасимволът ^ по подразбиране съвпада само в началото на въведения текст, а метасимволът $ съвпада само в края на текста. Вътрешните разделители на редове в текста няма да съвпадат с ^ и $.

Ако обаче трябва да третирате текста като многоредов, така че ^ да съвпада след всеки разделител на ред в текста и $ да съвпада преди всеки разделител, тогава можете да включите модификатора /m.

Метасимволите \A и \Z са подобни на ^ и $, но не се влияят от модификатора /m, т.е. те винаги съвпадат само с началото и края на целия въведен текст.

Метазнак. по подразбиране съвпада с всеки знак, но ако изключите модификатора /s, тогава. няма да съответства на разделителите на редовете.

TRegExpr интерпретира разделителите на редовете, както се препоръчва на www.unicode.org:

^ съвпада с началото на въведения текст и също, ако е включен модификатор /m, точката непосредствено след \x0D\x0A , \x0A или \x0D (ако използвате версията на Unicode

$ съвпада с края на въведения текст и също, ако е включен модификаторът /m, точката непосредствено пред \x0D\x0A , \x0A или \x0D (ако използвате Unicode версията на TRegExpr, тогава също \x2028 или \ x2029 или \x0B или \x0C или \x85). Имайте предвид, че не съвпада в последователността \x0D\x0A.

Съвпада с всеки знак, но ако модификаторът r /s е деактивиран, тогава. не съвпада с \x0D\x0A и \x0A и \x0D (ако използвате Unicode версията на TRegExpr, тя не съвпада с \x2028 и \x2029 и \x0B и \x0C и \x85).

Обърнете внимание, че ^.*$ (моделът за празния низ) не съответства на празния низ като \x0D\x0A, но съвпада с \x0A\x0D.

Можете да преконфигурирате горното поведение, когато обработвате многоредови текстове - вижте описанията на свойствата LineSeparators и LinePairedSeparator, например, можете да преконфигурирате да използвате само Unix разделители на редове \n или само DOS/Windows разделители \r\n или смесени разделители (или конфигуриран по подразбиране) или дори дефинирайте свои собствени разделители на редове!

Метасимволи - стандартни списъци със знаци

\w буквено-цифров знак или "_" \W не \w \d цифров знак \D не \d \s всеки знак за "празно пространство" (по подразбиране е [ \t\n\r\f]) \S не \ s

Стандартните списъци \w , \d и \s могат също да се използват в списъци със знаци.

Примери:

foob\dr намира "foob1r", ""foob6r" и т.н., но не и "foobar", "foobbr" и т.н. foob[\w\s]r намира "foobar", "foob r", " foobbr" и т.н. но не и "foob1r", "foob=r" и т.н.

Метасимволи - опции

Можете да дефинирате списък с опции, като използвате метасимвола | за да ги разделите, например fee|fie|foe ще съответства на fee или fie или foe , (същото като f(e|i|o)e). Като първа опция се възприема всичко от предишния метасимвол (или [ или от началото на израза до първия метасимвол |, като последна опция - всичко от последния | до края на израза или до най-близкия метасимвол) . Обикновено, за да се избегне объркване, наборът от опции винаги е ограден в скоби, дори ако това може да се направи без.

Опциите се опитват, като се започне от първата и опитите се завършват веднага щом е възможно да се избере такава, в която цялата следваща част от израза съвпада (за повече подробности вижте механизма на работа). Това означава, че вариантите няма непременно да осигурят алчно поведение. Например, ако приложите израза foo|foot към входния низ barefoot, той ще намери foo, защото това е първата опция, която позволява съвпадение на целия израз.

Обърнете внимание, че метасимволът | се възприема като обикновен знак в списъци със знаци, например означава точно същото като .

Примери:

foo(bar|foo) съответства на "foobar" или "foofoo".

Метазнаци – подизрази

Метасимволите (...) също могат да се използват за указване на подизрази

  • След като завършите търсенето на израз, можете да получите достъп до всеки подизраз, като използвате свойствата MatchPos, MatchLen и Match, както и да заместите подизрази в шаблон, като използвате метода Substitute).

Подизразите са номерирани отляво надясно, в реда, в който се появяват отварящите скоби.

Първият подизраз има номер 1 (целият израз е 0", може да бъде достъпен в Substitute или $0", или $&).

Примери:

(foobar)(8,10) намира низ, съдържащ 8, 9 или 10 копия на "foobar" foob(|a+)r намира "foob0r", "foob1r", "foobar", "foobaar", "foobaar" и т.н. .

Метасимволи - обратни връзки

Метасимволите от \1 до \9 се третират като обратни връзки. \ съответства на намерения преди това подизраз # .

Примери:

(.)\1+ намира "aaaa" и "cc". (.+)\1+ също съвпада с "abab" и "123123" ([""]?)(\d+)\1 съвпада с "13" (в двойни кавички), или "4" (в единични кавички) или 77 (без кавички) и др.

Модификатори

Модификаторите се използват за промяна на режимите на работа на TRegExpr.

Можете да промените модификаторите по няколко начина.

Всеки модификатор може да бъде променен с помощта на специална конструкция (?...) вътре в регулярен израз.

Можете също така да присвоите стойност на съответното свойство на екземпляра на обекта TRegExpr (например ModifierX за промяна на модификатора /x или ModifierStr за промяна на няколко модификатора наведнъж). Стойностите по подразбиране за нови екземпляри на обекти TRegExpr са дефинирани в , например RegExprModifierX дефинира стойността по подразбиране за ModifierX.

i

Режим без регистрация (по подразбиране използва езика по подразбиране, избран в операционната система), (вижте също InvertCase)

м

с

ж

Не е стандартен модификатор. Като го изключите, вие превключвате всички повторители в режим „неалчен“ (този модификатор е активиран по подразбиране). Тези. Ако го деактивирате, всички + работят като +? , * Как *? и т.н.

х

Позволява ви да форматирате шаблона, за да го направите по-лесен за четене (вижте описанието по-долу).

r

Не е стандартен модификатор. Ако е активирано, тогава диапазони тип a-zвключва също буквата ё, A-Z включва Ё, а a-Z включва всички руски букви като цяло.

Модификаторът /x кара TRegExpr да игнорира интервали, табулатори и разделители на редове, което позволява текстът на израза да бъде форматиран. Освен това, ако се срещне символът #, всички следващи знаци до края на реда се третират като коментар, например:

((abc) # Коментар 1 | # Интервалите в израза също се игнорират (efg) # Коментар 2)

Естествено, това означава, че ако трябва да вмъкнете интервал, разделител, разделител на ред или # в израз, тогава в разширен (/x) режим това може да стане само като ги предхождате с / или използвате /xnn (в списъци със знаци , всички тези знаци се третират както обикновено)

Perl разширения

(?imsxr-imsxr)

Позволява ви да променяте стойностите на модификатора

Примери:

(?i)Санкт-Петербург намира „Санкт-Петербург“ и „Санкт-Петербург“ (?i)Санкт-(?-i)Петербург намира „Санкт-Петербург“, но не и „Санкт-Петербург“ (?i)(Св. -)?Петербург намира "Санкт-Петербург" и "санкт-петербург" ((?i)Санкт-)?Петербург намира "санкт-Петербург", но не и "санкт-петербург"