Skip to content

Регулярни изрази (RegEx)

Въведение

Регулярните изрази са удобен начин за описване на модели на текст.

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

По-долу е пълният списък със справки за регулярни изрази.

Символи

Прости съвпадения

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

RegEx Съвпадения
foobar foobar

Непечатаеми символи (кодове за избягване)

За да посочите символ по неговия Unicode код, използвайте префикса \x, последван от хексадецималния код. За 3-4 цифрен код (след U+00FF), поставете кода в скоби.

RegEx Съвпадения
\xAB     символ с 2-цифрен хекс код AB
\x{AB20} символ с 1..4-цифрен хекс код AB20
foo\x20bar foo bar (обърнете внимание на интервала в средата)

Има редица предварително дефинирани кодове за избягване за непечатаеми символи, подобно на езика C:

RegEx Съвпадения
\t табулация (HT/TAB), същото като \x09
\n нов ред (LF), същото като \x0a
\r връщане назад (CR), същото като \x0d
\f форматиране на страница (FF), същото като \x0c
\a аларма (BEL), същото като \x07
\e избягване (ESC), същото като \x1b
\cA ... \cZ chr(0) до chr(25). Например, \cI съвпада с таб-символа. Малките букви "a"..."z" също са поддържани.

Избягване

За да представите специален символ за регулярни изрази (един от .+*?|\()[]{}^$), поставете пред него обратна наклонена черта \. Буквалната обратна наклонена черта също трябва да бъде ескейпната.

RegEx Съвпадения
\^FooBarPtr ^FooBarPtr, това е ^ и не начало на линия
\[a\] [a], това не е клас от символи

Класове символи

Потребителски класове символи

Класът символи е списък от символи в квадратни скоби []. Класът съвпада с всякакъв единичен символ, изброен в този клас.

RegEx Съвпадения
foob[aeiou]r foobar, foober и т.н., но не foobbr, foobcr и т.н.

Можете да "инвертирате" класа - ако първият символ след [ е ^, тогава класът съвпада с всеки символ освен символите, изброени в класа.

RegEx Съвпадения
foob[^aeiou]r foobbr, foobcr и т.н., но не foobar, foober и т.н.

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

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

Ако искате ] като част от класа, може да го поставите в началото на списъка или да го избегнете с обратна наклонена черта.

RegEx Съвпадения
[-az]     a, z и -
[az-]     a, z и -
[a\-z]   a, z и -
[a-z]     символи от a до z
[\n-\x0D] символи от chr(10) до chr(13)

Мета-Символ Точка

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

. не действа като мета-клас вътре в потребителските класове символи. [.] означава буквален ".".

Мета-Класове

Има редица предварително дефинирани класове символи, които правят регулярните изрази по-компактни, "мета-класове":

RegEx Съвпадения
\w   буквено-цифров символ, включително _
\W   не-буквено-цифров символ
\d   цифров символ (същото като [0-9])
\D   не-цифров символ
\s   всякакво пространство (същото като [ \t\n\r\f])
\S   не-пространствен символ
\h   хоризонтално пространство: табулацията и всички символи в категорията "разделител на пространство" от Unicode
\H не е хоризонтално пространство
\v вертикално пространство: всички символи, третирани като нови редове в стандарта Unicode
\V не е вертикално пространство
\R прекъсване на реда в Unicode: LF, двойка CR LF, CR, FF (форматиране на страница), VT (вертикална табулация), U+0085, U+2028, U+2029

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

RegEx Съвпадения
foob\dr     foob1r, foob6r и т.н., но не foobar, foobbr и т.н.
foob[\w\s]r foobar, foob r, foobbr и т.н., но не foob1r, foob=r и т.н.

TRegExpr

Свойствата SpaceChars и WordChars определят класовете на символите \w, \W, \s, \S.

Така можете да преопределите тези класове.

Граници

Граници на линията

Мета-символ Съвпадения
^  съвпадение с нулева дължина в началото на линията
$  съвпадение с нулева дължина в края на линията
\A съвпадение с нулева дължина в самото начало
\z съвпадение с нулева дължина в самия край
\Z като \z, но също така съвпада преди последния нов ред
\G съвпадение с нулева дължина в края на предишното съвпадение

Примери:

RegEx Съвпадения
^foobar foobar само ако е в началото на линията
foobar$ foobar само ако е в края на линията
^foobar$ foobar само ако е единственият низ в линията
foob.r   foobar, foobbr, foob1r и т.н.

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

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

TRegExpr

Ако използвате Unicode версия, тогава ^/$ също съвпада с \x2028, \x2029, \x0B, \x0C или \x85.

Мета-символът \A съвпада с позицията с нулева дължина в самото начало на входния низ, \z - в самия край. Те игнорират модификатора /m. \Z е като \z, но също така съвпада преди последния разделител на редове (LF и CR LF). Поведението на \A, \z, \Z е направено както в повечето основни регулярни двигатели (Perl, PCRE и др.).

Обърнете внимание, че ^.*$ не съвпада с низ между \x0D\x0A, защото това е неразделим разделител на редове. Но той съвпада с празния низ в последователността \x0A\x0D, защото това са 2 разделителя на редове в грешен ред.

TRegExpr

Обработката на многоредов текст може да бъде настроена с помощта на свойствата LineSeparators и UseLinePairedBreak.

Така можете да използвате разделители в Unix стил \n или в стил DOS/Windows \r\n или да ги смесите заедно (както е описано по-горе в поведението по подразбиране).

Ако предпочитате математически коректно описание, можете да го намерите на www.unicode.org.

Граници на думи

RegEx Съвпадения
\b граница на дума
\B  не е граница на дума

Границата на дума \b е мястото между два символа, което има \w от едната страна и \W от другата страна (във всяка посока).

Квантификация

Квантификатори

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

RegEx Съвпадения
{n}   точно n пъти
{n,}   поне n пъти
{,m}   не повече от m пъти (само с AllowBraceWithoutMin)
{n,m} поне n, но не повече от m пъти
*     нула или повече, подобно на {0,}
+   един или повече, подобно на {1,}
?   нула или един, подобно на {0,1}

Така цифрите в къдравите скоби {n,m}, определят минималния брой пъти n и максималния m.

{n} е еквивалентно на {n,n} и съвпада точно n пъти. {n,} съвпада n или повече пъти.

Вариантът {,m} се поддържа само ако свойството AllowBraceWithoutMin е зададено.

Няма практически лимит за стойностите n и m (лимитът е максималната стойност на 32-битово цяло число със знак).

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

RegEx Съвпадения
foob.*r     foobar, foobalkjdflkj9r и foobr
foob.+r     foobar, foobalkjdflkj9r но не foobr
foob.?r     foobar, foobbr и foobr но не foobalkj9r
fooba{2}r   foobaar
fooba{2,}r foobaar', foobaaar, foobaaaar и т.н.
fooba{2,3}r foobaar или foobaaar но не foobaaaar
(foobar){8,10} 8...10 инстанции на foobar (() е група)

Жадност

Квантификаторите в "жаден" режим вземат възможно най-много, в "мързелив" режим - възможно най-малко.

По подразбиране всички квантификатори са "жадни". Добавете символа ? за да направите всеки квантификатор "мързелив".

За низ abbbbc:

RegEx Съвпадения
b+ bbbb
b+? b
b*? празен низ
b{2,3}? bb
b{2,3} bbb

Можете да превключите всички квантификатори в "мързелив" режим (модификатор /g, по-долу използваме промяна на модификатора в линия).

RegEx Съвпадения
(?-g)b+ b

Притежателен Квантификатор

Синтаксисът е: a++, a*+, a?+, a{2,4}+. В момента това се поддържа само за прости скоби, но не и за скоби след група като (foo|bar){3,5}+.

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

Избор

Изразите в избора се разделят с вертикална черта |.

Така fee|fie|foe ще съвпадне с който и да е от fee, fie или foe в целевия низ (както и f(e|i|o)e).

Първият израз включва всичко от последния разделител на модела ((, [ или началото на модела) до първия |, а последният израз съдържа всичко от последния | до следващия разделител на модела.

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

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

Например, регулярният израз foo|foot в низ barefoot ще съвпадне с foo. Просто първият израз, който съвпада.

Също така помнете, че | се тълкува като буквален символ в квадратни скоби, така че ако напишете [fee|fie|foe] наистина съвпадате само с [feio|].

RegEx Съвпадения
foo(bar|foo) foobar или foofoo

Групи

Скобите () се използват за дефиниране на групи (т.е. подизрази).

Групите се номерират от ляво на дясно по тяхната отваряща скоба (включително вложените групи). Първата група има индекс 1. Целият регекс има индекс 0.

Обратни препратки

Мета-символите \1 до \9 се тълкуват като обратни препратки към групи. Те съвпадат с предварително намерената група с посочения индекс.

Мета символът \g последван от число също се тълкува като обратни препратки към групи. Може да бъде последван от многоцифрено число.

RegEx Съвпадения
(.)\1+   aaaa и cc
(.+)\1+ също abab и 123123
(.)\g1+  aaaa и cc

RegEx (['"]?)(\d+)\1 съвпада с "13" (в двойни кавички), или '4' (в единични кавички) или 77 (без кавички) и т.н.

Именувани Групи и Обратни Препратки

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

За създаване на именувана група, използвайте (?<name>pattern) или (?'name'pattern), където name е името на групата и pattern е регулярният израз, който искате да уловите.

Обратните връзки ви позволяват да съвпадате същия текст, както група е съвпадала преди. Именуваните обратни връзки използват \k<name>, където name е името на групата, която искате отново да съвпадне.

TRegExpr поддържа също версията на Perl: (?P<name>pattern) за дефиниране на именувана група и (?P=name) за обратни връзки.

Пример

RegEx Съвпадения
(?P<qq>['"])\w+(?P=qq) "word" и 'word'

Съвпадащ Резултат

Началото на съобщения за съвпадение може да бъде зададено с \K.

По подразбиране целият текст, покрит от модел, се счита за съвпадащ. Въпреки това е възможно изрично да се зададе какво ще бъде съобщено.

Моделът a\Kb ще изисква текстът да съдържа "ab". Но само "b" ще бъде съобщено като съвпадение. Може да има няколко \K в модел, последният ще зададе позицията на началото на съвпадението. Само \K в активни части на модела се вземат предвид. Напр. a(\Kb)? няма да вземе предвид \K, ако няма "b". Залавянията могат да съществуват извън съвпадението, зададено от \K.

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

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

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

Модификаторите са за промяна на поведението на регулярните изрази.

Можете да зададете модификаторите глобално във вашата система или да ги промените вътре в регулярния израз, използвайки (?imsxr-imsxr).

TRegExpr

За промяна на модификаторите използвайте ModifierStr или съответните свойства на TRegExpr Modifier*.

Стойностите по подразбиране са дефинирани в глобалнипроменливи. Например, глобалната променлива RegExprModifierX дефинира стойността по подразбиране за свойството ModifierX.

i, без учет на регистъра

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

m, многостранични низове

Третирайте низа като множество линии. Така ^ и $ съвпадат с началото или края на всяка линия навсякъде в низа.

Вижте също Граници на линията.

s, единични линии низове

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

Вижте също Граници на линията, които обикновено не би съвпадал.

g, жадност

Превключването му Изкл ще превключи квантификаторите в нежаден режим.

Така, ако модификаторът /g е Изкл, тогава + работи като +?, * като *? и така нататък.

По подразбиране този модификатор е Вкл.

x, Разширен синтаксис

Позволява коментиране на регулярен израз и разделянето му на множество линии.

Ако модификаторът е Вкл, игнорираме всички интервали, които не са с обратна наклонена черта или в клас от символи.

И символът # разделя коментарите.

Забележете, че можете да използвате празни линии за форматиране на регулярен израз за по-добра четимост:

(
(abc) # коментар 1
#
(efg) # коментар 2
)

Това също означава, че ако искате истински интервали или символи # в модела (извън клас от символи, където те не са засегнати от /x), ще трябва да ги ескейпнете или да ги кодирате чрез октални или хексадецимални ескейпи.

r, Руски диапазони

TRegExpr единствен модификатор.

В руската ASCII таблица символите ё/Ё са поставени отделно от другите.

Големите и малките руски символи са в отделни диапазони, което е същото като при английските символи, но въпреки това исках някаква кратка форма.

С този модификатор вместо [а-яА-ЯёЁ] можете да напишете [а-Я], ако имате нужда от всички руски символи.

Когато модификаторът е Вкл:

RegEx Съвпадения
а-я символи от а до я и ё
А-Я символи от А до Я и Ё
а-Я всички руски символи

Модификаторът е зададен на Вкл по подразбиране.

Твърдения (гледане напред, гледане назад)

Положително твърдение за гледане напред: foo(?=bar) съвпада с "foo" само преди "bar", и "bar" е изключен от съвпадението.

Отрицателно твърдение за гледане напред: foo(?!bar) съвпада с "foo" само ако не е последвано от "bar".

Положително твърдение за гледане назад: (?<=foo)bar съвпада с "bar" само след "foo", и "foo" е изключен от съвпадението.

Отрицателно твърдение за гледане назад: (?<!foo)bar съвпада с "bar" само ако не е предшествано от "foo".

Ограничения:

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

Незалавящи Групи

Синтаксисът е такъв: (?:expr).

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

RegEx Съвпадения
(https?|ftp)://([^/\r\n]+) в https://sorokin.engineer съвпада https и sorokin.engineer
(?:https?|ftp)://([^/\r\n]+) в https://sorokin.engineer съвпада само sorokin.engineer

Атомни Групи

Синтаксисът е такъв: (?>expr|expr|...).

Атомните групи са специален случай на незалавящи групи. Описание на тях.

Вградени Модификатори

Синтаксис за един модификатор: (?i) за включване, и (?-i) за изключване. Много модификатори са позволени така: (?msgxr-imsgxr).

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

И ако е вътре в група, то ще засегне само тази група - конкретно частта от групата, която следва модификаторите. Така в ((?i)Saint)-Petersburg то засяга само групата ((?i)Saint), така че ще съвпадне с saint-Petersburg, но не и с saint-petersburg.

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

RegEx Съвпадения
(?i)Saint-Petersburg       Saint-petersburg и Saint-Petersburg
(?i)Saint-(?-i)Petersburg Saint-Petersburg, но не Saint-petersburg
(?i)(Saint-)?Petersburg   Saint-petersburg и saint-petersburg
((?i)Saint-)?Petersburg   saint-Petersburg, но не saint-petersburg

Коментари

Синтаксисът е такъв: (?#text). Текстът в скобите се игнорира.

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

Рекурсия

Синтаксисът е (?R), псевдонимът е (?0).

Регексът a(?R)?z съвпада с една или повече букви "a", последвани от точно същия брой букви "z".

Основната цел на рекурсията е да съвпадне с балансирани конструкции или вложени конструкции. Общият регекс е b(?:m|(?R))*e където "b" е това, което започва конструкцията, "m" е това, което може да се случи в средата на конструкцията, и "e" е това, което се случва в края на конструкцията.

Ако това, което може да се появи в средата на балансираната конструкция, може също така да се появи самостоятелно без началните и крайните части, тогава общият регекс е b(?R)*e|m.

Подизвиквания на подпрограми

Синтаксисът за извикване на номерирани групи: (?1) ... (?90) (максималният индекс е ограничен от кода).

Синтаксисът за извикване на именувани групи: (?P>name). Също така се поддържа синтаксисът (?&name), \g<name> и \g'name'

Това е като рекурсия, но извиква само кода на група за залавяне с посочения индекс.

Категории на Unicode

Стандартът на Unicode има имена за категории на символи. Това са 2-буквени низове. Например "Lu" е главни букви, "Ll" е малки букви. И 1-буквена по-голяма категория "L" е всички букви.

  • Cc - Контрол
  • Cf - Формат
  • Co - Лична употреба
  • Cs - Заместник
  • Ll - Малка буква
  • Lm - Модифицираща буква
  • Lo - Друга буква
  • Lt - Буква с начална главна
  • Lu - Главна буква
  • Mc - Разделител за маркиране
  • Me - Затварящ маркер
  • Mn - Маркер без интервал
  • Nd - Десетичен номер
  • Nl - Буквен номер
  • No - Друг номер
  • Pc - Свързваща пунктуация
  • Pd - Тире пунктуация
  • Pe - Затваряща пунктуация
  • Pf - Крайна пунктуация
  • Pi - Начална пунк
  • Po - Друга пунктуация
  • Ps - Отваряща пунктуация
  • Sc - Символ на валута
  • Sk - Модифициращ символ
  • Sm - Математически символ
  • So - Друг символ
  • Zl - Разделител на линии
  • Zp - Разделител на параграфи
  • Zs - Разделител на пространство

Мета-символът \p означава един Unicode символ от определена категория. Синтаксис: \pL и \p{L} за имена с 1 буква, \p{Lu} за имена с 2 букви.

Мета-символът \P е инвертиран, той означава един Unicode символ не в специфицираната категория.

Тези мета-символи се поддържат и в класовете на символите.

Следдума

В този древен блог пост от предишния век илустрирам някои употреби на регулярни изрази.