Для апрацоўкі рэгулярных выразаў у Python мы выкарыстоўваем модуль re са стандартнай бібліятэкі. Гэта дазваляе здабываць, замяняць і падзяляць радкі з дапамогай шаблонаў рэгулярных выразаў.
- re — Regular expression operations — Python 3.10.0 Documentation
- Regular Expression HOWTO — Python 3.10.0 Documentation
У гэтым раздзеле мы спачатку растлумачым функцыі і метады модуля re.
- Кампіляцыя шаблонаў рэгулярных выразаў:
compile()
- адпавядаць аб’екту
- Праверце, ці супадае пачатак радка, здабывайце:
match()
- Праверце супадзенні не абмяжоўваючыся пачаткам:
search()
- Праверце, ці супадае ўвесь радок:
fullmatch()
- Атрымаць спіс усіх адпаведных частак:
findall()
- Атрымаць усе адпаведныя часткі ў якасці ітэратара:
finditer()
- Замяніце адпаведную частку:
sub()
,subn()
- Раздзяленне радкоў з шаблонамі рэгулярных выразаў:
split()
Пасля гэтага я растлумачу метасімвалы (спецыяльныя сімвалы) і спецыяльныя паслядоўнасці рэгулярных выразаў, якія можна выкарыстоўваць у модулі re. Па сутнасці, гэта стандартны сінтаксіс рэгулярных выразаў, але будзьце асцярожныя з устаноўкай сцягоў (асабліва re.ASCII).
- Метасімвалы рэгулярнага выразу, спецыяльныя паслядоўнасці і агаворкі ў Python
- Ўстаноўка сцяга
- Абмежавана сімваламі ASCII:
re.ASCII
- Не адчувальны рэгістр:
re.IGNORECASE
- Супастаўце пачатак і канец кожнага радка:
re.MULTILINE
- Пакажыце некалькі сцягоў
- Абмежавана сімваламі ASCII:
- Прагныя і непрагныя матчы
- Скампіляваць шаблон рэгулярных выразаў: compile()
- адпавядаць аб’екту
- Праверце, ці супадае пачатак радка, распакуйце: match()
- Праверце наяўнасць супадзенняў, не абмяжоўваючыся пачаткам, распакуйце: search()
- Праверце, ці супадае ўвесь радок: fullmatch()
- Атрымаць спіс усіх адпаведных частак: findall()
- Атрымаць усе адпаведныя часткі ў якасці ітэратара: finditer()
- Замяніць адпаведныя часткі: sub(), subn()
- Раздзяленне радкоў з шаблонамі рэгулярных выразаў: split()
- Метасімвалы рэгулярнага выразу, спецыяльныя паслядоўнасці і агаворкі ў Python
- Ўстаноўка сцяга
- Прагныя і непрагныя матчы
Скампіляваць шаблон рэгулярных выразаў: compile()
Ёсць два спосабы апрацоўкі рэгулярных выразаў у модулі re.
Запуск з функцыяй
Першы – гэта функцыя.re.match()
,re.sub()
Такія функцыі даступныя для выканання здабывання, замены і іншых працэсаў з выкарыстаннем шаблонаў рэгулярных выразаў.
Падрабязнасці функцый будуць апісаны пазней, але ва ўсіх іх першым аргументам з’яўляецца радок шаблону рэгулярных выразаў, а затым радок для апрацоўкі і гэтак далей. Напрыклад, у re.sub(), які выконвае замену, другі аргумент – гэта радок замены, а трэці аргумент – радок, які трэба апрацаваць.
import re
s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'
m = re.match(r'([a-z]+)@([a-z]+)\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
result = re.sub(r'([a-z]+)@([a-z]+)\.com', 'new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net
Звярніце ўвагу, што [a-z] у шаблоне рэгулярных выразаў у гэтым прыкладзе азначае любы сімвал ад a да z (гэта значыць алфавіт малога рэгістра), а + азначае паўтарэнне папярэдняга шаблону (у дадзеным выпадку [a-z]) адзін або некалькі разоў. [a-z]+ адпавядае любому радку, які паўтарае адзін або некалькі сімвалаў малога рэгістра.
. з’яўляецца метасімвалам (сімвалам з асаблівым значэннем) і павінен быць экранаваны зваротнай касой рысай.
Паколькі радкі шаблону рэгулярных выразаў часта выкарыстоўваюць шмат зваротнай касой рысы, зручна выкарыстоўваць неапрацаваныя радкі, як у прыкладзе.
Выконваецца ў метадзе шаблону рэгулярнага выразу
Другі спосаб апрацоўкі рэгулярных выразаў у модулі re – гэта метад аб’екта шаблону рэгулярных выразаў.
Выкарыстоўваючы re.compile(), вы можаце скампіляваць радок шаблону рэгулярнага выразу, каб стварыць аб’ект шаблону рэгулярнага выразу.
p = re.compile(r'([a-z]+)@([a-z]+)\.com')
print(p)
# re.compile('([a-z]+)@([a-z]+)\\.com')
print(type(p))
# <class 're.Pattern'>
re.match()
,re.sub()
Напрыклад, той жа працэс, што і гэтыя функцыі, можа быць выкананы як метады match(),sub() аб’ектаў рэгулярных выразаў.
m = p.match(s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
result = p.sub('new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net
Усе функцыі re.xxx(), апісаныя ніжэй, таксама прадстаўлены ў якасці метадаў аб’екта рэгулярнага выразу.
Калі вы паўтараеце працэс, які выкарыстоўвае той жа шаблон, больш эфектыўна генераваць аб’ект рэгулярнага выразу з дапамогай re.compile() і выкарыстоўваць яго вакол.
У наступным узоры кода функцыя выкарыстоўваецца без кампіляцыі для зручнасці, але калі вы хочаце выкарыстоўваць адзін і той жа шаблон паўторна, рэкамендуецца скампіляваць яго загадзя і выканаць як метад аб’екта рэгулярнага выразу.
адпавядаць аб’екту
match(), search() і г.д. вяртаюць аб’ект супастаўлення.
s = 'aaa@xxx.com'
m = re.match(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
print(type(m))
# <class 're.Match'>
Адпаведны радок і пазіцыя атрымліваюцца з дапамогай наступных метадаў аб’екта супастаўлення.
- Атрымаць месца правядзення матчу:
start()
,end()
,span()
- Атрымаць адпаведны радок:
group()
- Атрымаць радок для кожнай групы:
groups()
print(m.start())
# 0
print(m.end())
# 11
print(m.span())
# (0, 11)
print(m.group())
# aaa@xxx.com
Калі вы заключыце частку шаблону рэгулярнага выразу ў радок з дужкамі(), частка будзе апрацавана як група. У гэтым выпадку радок часткі, якая адпавядае кожнай групе ў groups(), можна атрымаць у выглядзе картэжа.
m = re.match(r'([a-z]+)@([a-z]+)\.([a-z]+)', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
print(m.groups())
# ('aaa', 'xxx', 'com')
Праверце, ці супадае пачатак радка, распакуйце: match()
match() вяртае аб’ект супастаўлення, калі пачатак радка супадае з шаблонам.
Як згадвалася вышэй, аб’ект супастаўлення можа быць выкарыстаны для вылучэння адпаведнага падрадка або проста для праверкі, ці было супадзенне.
match() будзе правяраць толькі пачатак. Калі ў пачатку няма адпаведнага радка, ён вяртае None.
s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'
m = re.match(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
m = re.match(r'[a-z]+@[a-z]+\.net', s)
print(m)
# None
Праверце наяўнасць супадзенняў, не абмяжоўваючыся пачаткам, распакуйце: search()
Як і match(), ён вяртае аб’ект супастаўлення, калі ён супадае.
Калі ёсць некалькі супадаючых частак, будзе вернута толькі першая адпаведная частка.
s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'
m = re.search(r'[a-z]+@[a-z]+\.net', s)
print(m)
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>
m = re.search(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
Калі вы хочаце атрымаць усе адпаведныя часткі, выкарыстоўвайце findall() або finditer(), як апісана ніжэй.
Праверце, ці супадае ўвесь радок: fullmatch()
Каб праверыць, ці адпавядае ўвесь радок шаблону рэгулярнага выразу, выкарыстоўвайце fullmatch(). Гэта карысна, напрыклад, каб праверыць, ці дзейнічае радок у якасці адраса электроннай пошты ці не.
Калі супадае ўвесь радок, вяртаецца аб’ект адпаведнасці.
s = 'aaa@xxx.com'
m = re.fullmatch(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
Калі ёсць несупадзеныя часткі (толькі частковыя супадзенні або іх няма наогул), вяртаецца None.
s = '!!!aaa@xxx.com!!!'
m = re.fullmatch(r'[a-z]+@[a-z]+\.com', s)
print(m)
# None
Fullmatch() быў дададзены ў Python 3.4. Калі вы хочаце зрабіць тое ж самае ў папярэдніх версіях, выкарыстоўвайце match() і адпаведны метасімвал $ у канцы. Калі ўвесь радок ад пачатку да канца не супадае, ён вяртае None.
s = '!!!aaa@xxx.com!!!'
m = re.match(r'[a-z]+@[a-z]+\.com$', s)
print(m)
# None
Атрымаць спіс усіх адпаведных частак: findall()
findall() вяртае спіс усіх адпаведных падрадкоў. Звярніце ўвагу, што элементы спісу з’яўляюцца не аб’ектамі адпаведнасці, а радкамі.
s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'
result = re.findall(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(result)
# ['aaa@xxx.com', 'bbb@yyy.com', 'ccc@zzz.net']
Колькасць супадзеных частак можна праверыць з дапамогай убудаванай функцыі len(), якая вяртае колькасць элементаў у спісе.
print(len(result))
# 3
Групаванне з дужкамі() у шаблоне рэгулярнага выразу вяртае спіс картэжаў, элементамі якіх з’яўляюцца радкі кожнай групы. Гэта эквівалентна groups() у аб’екце супастаўлення.
result = re.findall(r'([a-z]+)@([a-z]+)\.([a-z]+)', s)
print(result)
# [('aaa', 'xxx', 'com'), ('bbb', 'yyy', 'com'), ('ccc', 'zzz', 'net')]
Групавыя дужкі () могуць быць укладзенымі, таму, калі вы таксама хочаце атрымаць супадзенне цалкам, проста ўкладзеце ўсё супадзенне ў дужкі ().
result = re.findall(r'(([a-z]+)@([a-z]+)\.([a-z]+))', s)
print(result)
# [('aaa@xxx.com', 'aaa', 'xxx', 'com'), ('bbb@yyy.com', 'bbb', 'yyy', 'com'), ('ccc@zzz.net', 'ccc', 'zzz', 'net')]
Калі супадзенне не знойдзена, вяртаецца пусты картэж.
result = re.findall('[0-9]+', s)
print(result)
# []
Атрымаць усе адпаведныя часткі ў якасці ітэратара: finditer()
finditer() вяртае ўсе адпаведныя часткі ў выглядзе ітэратара. Элементы не ўяўляюць сабой радкі, як findall(), а аб’екты супадзення, так што вы можаце атрымаць пазіцыю (індэкс) супаданых частак.
Сам ітэратар не можа быць раздрукаваны з дапамогай print(), каб атрымаць яго змесціва. Калі вы выкарыстоўваеце ўбудаваную функцыю next() або аператар for, вы можаце атрымаць змесціва адзін за адным.
s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'
result = re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(result)
# <callable_iterator object at 0x10b0efa90>
print(type(result))
# <class 'callable_iterator'>
for m in result:
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
# <re.Match object; span=(13, 24), match='bbb@yyy.com'>
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>
Яго таксама можна пераўтварыць у спіс з дапамогай list().
l = list(re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s))
print(l)
# [<re.Match object; span=(0, 11), match='aaa@xxx.com'>, <re.Match object; span=(13, 24), match='bbb@yyy.com'>, <re.Match object; span=(26, 37), match='ccc@zzz.net'>]
print(l[0])
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
print(type(l[0]))
# <class 're.Match'>
print(l[0].span())
# (0, 11)
Калі вы хочаце атрымаць пазіцыю ўсіх супадаючых частак, запіс разумення спісу больш зручны, чым list().
print([m.span() for m in re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)])
# [(0, 11), (13, 24), (26, 37)]
Ітэратар выбірае элементы па парадку. Звярніце ўвагу, што калі вы паспрабуеце атрымаць больш элементаў пасля дасягнення канца, вы застанецеся ні з чым.
result = re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)
for m in result:
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
# <re.Match object; span=(13, 24), match='bbb@yyy.com'>
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>
print(list(result))
# []
Замяніць адпаведныя часткі: sub(), subn()
Выкарыстоўваючы sub(), вы можаце замяніць адпаведную частку іншым радком. Заменены радок будзе вернуты.
s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'
result = re.sub(r'[a-z]+@[a-z]+\.com', 'new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net
print(type(result))
# <class 'str'>
Пры групоўцы з дужкамі(), адпаведны радок можа быць выкарыстаны ў заменены радок.
Па змаўчанні падтрымліваецца наступнае: Звярніце ўвагу, што для звычайных радкоў, якія не з’яўляюцца сырымі радкамі, зваротная касая рыса павінна быць пералічана перад зваротнай касой рысай, каб пазбегнуць зваротнай касой рысы.
\1 | Першая дужка |
\2 | Другая дужка |
\3 | Трэцяя дужка |
result = re.sub(r'([a-z]+)@([a-z]+)\.com', r'\1@\2.net', s)
print(result)
# aaa@xxx.net, bbb@yyy.net, ccc@zzz.net
?P<xxx>
Калі вы назавеце групу, напісаўшы гэта ў пачатку дужак шаблону рэгулярных выразаў, вы можаце ўказаць яе, выкарыстоўваючы імя замест нумара, як паказана ніжэй.\g<xxx>
result = re.sub(r'(?P<local>[a-z]+)@(?P<SLD>[a-z]+)\.com', r'\g<local>@\g<SLD>.net', s)
print(result)
# aaa@xxx.net, bbb@yyy.net, ccc@zzz.net
Колькасць аргументаў вызначае максімальную колькасць замен. Будзе заменены толькі лік з левага боку.
result = re.sub(r'[a-z]+@[a-z]+\.com', 'new-address', s, count=1)
print(result)
# new-address, bbb@yyy.com, ccc@zzz.net
subn() вяртае картэж падстаўленага радка (тое ж, што вяртае значэнне sub()) і колькасць падстаўленых частак (колькасць, якая адпавядае шаблону).
result = re.subn(r'[a-z]+@[a-z]+\.com', 'new-address', s)
print(result)
# ('new-address, new-address, ccc@zzz.net', 2)
Метад задання аргументаў такі ж, як і sub(). Вы можаце выкарыстоўваць частку, згрупаваную ў дужках, або ўказаць колькасць аргументаў.
result = re.subn(r'(?P<local>[a-z]+)@(?P<SLD>[a-z]+)\.com', r'\g<local>@\g<SLD>.net', s)
print(result)
# ('aaa@xxx.net, bbb@yyy.net, ccc@zzz.net', 2)
result = re.subn(r'[a-z]+@[a-z]+\.com', 'new-address', s, count=1)
print(result)
# ('new-address, bbb@yyy.com, ccc@zzz.net', 1)
Раздзяленне радкоў з шаблонамі рэгулярных выразаў: split()
split() падзяляе радок на частку, якая адпавядае шаблону, і вяртае яе ў выглядзе спісу.
Звярніце ўвагу, што першае і апошняе супадзенні будуць утрымліваць пустыя радкі ў пачатку і ў канцы выніковага спісу.
s = '111aaa222bbb333'
result = re.split('[a-z]+', s)
print(result)
# ['111', '222', '333']
result = re.split('[0-9]+', s)
print(result)
# ['', 'aaa', 'bbb', '']
Аргумент maxsplit вызначае максімальную колькасць расколаў (частак). Разбіваецца толькі падлік з левага боку.
result = re.split('[a-z]+', s, 1)
print(result)
# ['111', '222bbb333']
Метасімвалы рэгулярнага выразу, спецыяльныя паслядоўнасці і агаворкі ў Python
Асноўныя метасімвалы рэгулярных выразаў (спецыяльныя сімвалы) і спецыяльныя паслядоўнасці, якія можна выкарыстоўваць у модулі Python 3 re, выглядаюць ніжэй
метаперсанаж | змест |
---|---|
. | Любы асобны сімвал, акрамя новага радка (уключаючы новы радок са сцягам DOTALL) |
^ | Пачатак радка (таксама адпавядае пачатку кожнага радка са сцягам MULTILINE) |
$ | Канец радка (таксама адпавядае канца кожнага радка са сцягам MULTILINE) |
* | Паўтарыце папярэдні ўзор больш за 0 разоў |
+ | Паўтарыце папярэднюю схему хоць бы раз. |
? | Паўтарыце папярэдні ўзор 0 або 1 раз |
{m} | Паўтарыце папярэдні ўзор m разоў |
{m, n} | Апошні ўзор.m ~n паўтарыць |
[] | Набор сімвалаў[] Супадае з любым з гэтых сімвалаў |
| | АБОA|B Супадае з шаблонам A або B |
асаблівая паслядоўнасць | змест |
---|---|
\d | Дзесятковыя лікі Unicode (абмежаваны лічбамі ASCII сцягам ASCII) |
\D | \d Маецца на ўвазе супрацьлеглае гэтаму. |
\s | Прабелы Unicode (абмежаваны прабеламі ASCII сцягам ASCII) |
\S | \s Маецца на ўвазе супрацьлеглае гэтаму. |
\w | Словавыя сімвалы і знакі падкрэслення ў Unicode (абмежаваны літарна-лічбавымі сімваламі ASCII і падкрэсленнямі сцягам ASCII) |
\W | \w Маецца на ўвазе супрацьлеглае гэтаму. |
Не ўсе з іх пералічаныя ў гэтай табліцы. Поўны спіс глядзіце ў афіцыйнай дакументацыі.
Таксама звярніце ўвагу, што некаторыя значэнні адрозніваюцца ў Python 2.
Ўстаноўка сцяга
Як паказана ў табліцы вышэй, некаторыя метасімвалы і спецыяльныя паслядоўнасці змяняюць свой рэжым у залежнасці ад сцяга.
Тут прыкрыты толькі галоўныя сцягі. Астатняе глядзіце ў афіцыйнай дакументацыі.
Абмежавана сімваламі ASCII: re.ASCII
\w
Гэта таксама будзе адпавядаць двухбайтовым кандзі, літарна-лічбавым сімвалам і г.д. па змаўчанні для радкоў Python 3. Гэта не эквівалентна наступнаму, таму што гэта не стандартны рэгулярны выраз.[a-zA-Z0-9_]
m = re.match(r'\w+', '漢字ABC123')
print(m)
# <re.Match object; span=(0, 11), match='漢字ABC123'>
m = re.match('[a-zA-Z0-9_]+', '漢字ABC123')
print(m)
# None
Калі вы пакажаце re.ASCII для сцягоў аргументаў у кожнай функцыі або дадасце наступны ўбудаваны сцяг у пачатак радка шаблону рэгулярнага выразу, ён будзе адпавядаць толькі сімвалам ASCII (ён не будзе адпавядаць двухбайтовым японскім, літарна-лічбавым сімвалам і г.д. .).(?a)
У гэтым выпадку наступныя два раўназначныя.\w
#ERROR![a-zA-Z0-9_]
m = re.match(r'\w+', '漢字ABC123', flags=re.ASCII)
print(m)
# None
m = re.match(r'(?a)\w+', '漢字ABC123')
print(m)
# None
Тое ж самае ставіцца і пры кампіляцыі з дапамогай re.compile(). Выкарыстоўвайце сцягі аргументаў або ўбудаваныя сцягі.
p = re.compile(r'\w+', flags=re.ASCII)
print(p)
# re.compile('\\w+', re.ASCII)
print(p.match('漢字ABC123'))
# None
p = re.compile(r'(?a)\w+')
print(p)
# re.compile('(?a)\\w+', re.ASCII)
print(p.match('漢字ABC123'))
# None
ASCII таксама даступны як кароткая форма re. A. Вы можаце выкарыстоўваць любы.
print(re.ASCII is re.A)
# True
На \W, супрацьлегласць \W, таксама ўплываюць рэ.ASCII і ўбудаваныя сцягі.
m = re.match(r'\W+', '漢字ABC123')
print(m)
# None
m = re.match(r'\W+', '漢字ABC123', flags=re.ASCII)
print(m)
# <re.Match object; span=(0, 11), match='漢字ABC123'>
Як і ў выпадку \w, наступныя два супадаюць як аднабайтавыя, так і двухбайтавыя сімвалы па змаўчанні, але абмежаваныя аднабайтавымі сімваламі, калі паказаны сцягі re.ASCII або ўбудаваныя.
- Супастаўце лічбы
\d
- Супадае з пустым месцам
\s
- Супадае без лікаў
\D
- Супадае з любым непрабелам.
\S
m = re.match(r'\d+', '123')
print(m)
# <re.Match object; span=(0, 3), match='123'>
m = re.match(r'\d+', '123')
print(m)
# <re.Match object; span=(0, 3), match='123'>
m = re.match(r'\d+', '123', flags=re.ASCII)
print(m)
# <re.Match object; span=(0, 3), match='123'>
m = re.match(r'\d+', '123', flags=re.ASCII)
print(m)
# None
m = re.match(r'\s+', ' ') # full-width space
print(m)
# <re.Match object; span=(0, 1), match='\u3000'>
m = re.match(r'\s+', ' ', flags=re.ASCII)
print(m)
# None
Не адчувальны рэгістр:re.IGNORECASE
Па змаўчанні ён адчувальны да рэгістра. Каб адпавядаць абодвум, вам трэба ўключыць у шаблон як вялікія, так і малыя літары.
re.IGNORECASE
Калі гэта зададзена, яно будзе адпавядаць без уліку рэгістра. Эквівалентны сцягу i ў стандартных рэгулярных выразах.
m = re.match('[a-zA-Z]+', 'abcABC')
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>
m = re.match('[a-z]+', 'abcABC', flags=re.IGNORECASE)
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>
m = re.match('[A-Z]+', 'abcABC', flags=re.IGNORECASE)
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>
Вы можаце выкарыстоўваць менш або роўна.
- убудаваны сцяг
(?i)
- абрэвіятура
re.I
Супастаўце пачатак і канец кожнага радка:re.MULTILINE
^
Метасімвалы ў гэтым рэгулярным выразе адпавядаюць пачатку радка.
Па змаўчанні супастаўляецца толькі пачатак усяго радка, але наступныя таксама будуць адпавядаць пачатку кожнага радка. Эквівалентны сцягу m у стандартных рэгулярных выразах.re.MULTILINE
s = '''aaa-xxx
bbb-yyy
ccc-zzz'''
print(s)
# aaa-xxx
# bbb-yyy
# ccc-zzz
result = re.findall('[a-z]+', s)
print(result)
# ['aaa', 'xxx', 'bbb', 'yyy', 'ccc', 'zzz']
result = re.findall('^[a-z]+', s)
print(result)
# ['aaa']
result = re.findall('^[a-z]+', s, flags=re.MULTILINE)
print(result)
# ['aaa', 'bbb', 'ccc']
$
Супадае з канцом радка. Па змаўчанні супастаўляецца толькі канец усяго радка.re.MULTILINE
Калі вы пакажаце гэта, ён таксама будзе адпавядаць канцы кожнага радка.
result = re.findall('[a-z]+$', s)
print(result)
# ['zzz']
result = re.findall('[a-z]+$', s, flags=re.MULTILINE)
print(result)
# ['xxx', 'yyy', 'zzz']
Вы можаце выкарыстоўваць менш або роўна.
- убудаваны сцяг
(?m)
- абрэвіятура
re.M
Пакажыце некалькі сцягоў
|
Калі вы хочаце ўключыць некалькі сцягоў адначасова, выкарыстоўвайце гэта. У выпадку ўбудаваных сцягоў пасля кожнага сімвала павінна ісці літара, як паказана ніжэй.(?am)
s = '''aaa-xxx
漢漢漢-字字字
bbb-zzz'''
print(s)
# aaa-xxx
# 漢漢漢-字字字
# bbb-zzz
result = re.findall(r'^\w+', s, flags=re.M)
print(result)
# ['aaa', '漢漢漢', 'bbb']
result = re.findall(r'^\w+', s, flags=re.M | re.A)
print(result)
# ['aaa', 'bbb']
result = re.findall(r'(?am)^\w+', s)
print(result)
# ['aaa', 'bbb']
Прагныя і непрагныя матчы
Гэта агульная праблема з рэгулярнымі выразамі, а не толькі праблема з Python, але я напішу пра яе, таму што гэта, як правіла, выклікае ў мяне праблемы.
Па змаўчанні, ніжэй прагны матч, які адпавядае максімальна доўгай радкі.
*
+
?
s = 'aaa@xxx.com, bbb@yyy.com'
m = re.match(r'.+com', s)
print(m)
# <re.Match object; span=(0, 24), match='aaa@xxx.com, bbb@yyy.com'>
print(m.group())
# aaa@xxx.com, bbb@yyy.com
? пасля таго, як гэта прывядзе да непрагнага, мінімальнага супадзення, адпавядаючы максімальна кароткай радку.
*?
+?
??
m = re.match(r'.+?com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
print(m.group())
# aaa@xxx.com
Звярніце ўвагу, што прагнае супадзенне па змаўчанні можа адпавядаць нечаканым радкам.