Регулярни изрази (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 и т.н. |
Свойствата 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
.
Ако използвате Unicode версия, тогава
^
/$
също съвпада с\x2028
,\x2029
,\x0B
,\x0C
или\x85
.
Мета-символът \A
съвпада с позицията с нулева дължина в самото начало на
входния низ, \z
- в самия край. Те игнорират модификатора /m.
\Z
е като \z
, но също така съвпада преди последния разделител на редове (LF и
CR LF). Поведението на \A
, \z
, \Z
е направено както в повечето основни
регулярни двигатели (Perl, PCRE и др.).
Обърнете внимание, че ^.*$
не съвпада с низ между \x0D\x0A
, защото
това е неразделим разделител на редове. Но той съвпада с празния низ
в последователността \x0A\x0D
, защото това са 2 разделителя на редове в
грешен ред.
Обработката на многоредов текст може да бъде настроена с помощта на свойствата 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).
За промяна на модификаторите използвайте 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 символ не в
специфицираната категория.
Тези мета-символи се поддържат и в класовете на символите.
Следдума
В този древен блог пост от предишния век илустрирам някои употреби на регулярни изрази.