Як выкарыстоўваць модуль рэгулярных выразаў Python re (супадзенне, пошук, падмена і г.д.)

Бізнэс

Для апрацоўкі рэгулярных выразаў у Python мы выкарыстоўваем модуль re са стандартнай бібліятэкі. Гэта дазваляе здабываць, замяняць і падзяляць радкі з дапамогай шаблонаў рэгулярных выразаў.

У гэтым раздзеле мы спачатку растлумачым функцыі і метады модуля re.

  • Кампіляцыя шаблонаў рэгулярных выразаў:compile()
  • адпавядаць аб’екту
  • Праверце, ці супадае пачатак радка, здабывайце:match()
  • Праверце супадзенні не абмяжоўваючыся пачаткам:search()
  • Праверце, ці супадае ўвесь радок:fullmatch()
  • Атрымаць спіс усіх адпаведных частак:findall()
  • Атрымаць усе адпаведныя часткі ў якасці ітэратара:finditer()
  • Замяніце адпаведную частку:sub(),subn()
  • Раздзяленне радкоў з шаблонамі рэгулярных выразаў:split()

Пасля гэтага я растлумачу метасімвалы (спецыяльныя сімвалы) і спецыяльныя паслядоўнасці рэгулярных выразаў, якія можна выкарыстоўваць у модулі re. Па сутнасці, гэта стандартны сінтаксіс рэгулярных выразаў, але будзьце асцярожныя з устаноўкай сцягоў (асабліва re.ASCII).

  • Метасімвалы рэгулярнага выразу, спецыяльныя паслядоўнасці і агаворкі ў Python
  • Ўстаноўка сцяга
    • Абмежавана сімваламі ASCII:re.ASCII
    • Не адчувальны рэгістр:re.IGNORECASE
    • Супастаўце пачатак і канец кожнага радка:re.MULTILINE
    • Пакажыце некалькі сцягоў
  • Прагныя і непрагныя матчы

Скампіляваць шаблон рэгулярных выразаў: 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

Звярніце ўвагу, што прагнае супадзенне па змаўчанні можа адпавядаць нечаканым радкам.

Copied title and URL