Tavapäraste väljendite töötlemiseks Pythonis kasutame standardraamatukogu re-moodulit. See võimaldab väljavõtteid eraldada, asendada ja jagada stringid, kasutades regulaaravaldiste mustreid.
- re — Regular expression operations — Python 3.10.0 Documentation
- Regular Expression HOWTO — Python 3.10.0 Documentation
Selles jaotises selgitame kõigepealt re-mooduli funktsioone ja meetodeid.
- Regulaaravaldiste mustrite koostamine:
compile()
- mängu objekt
- Kontrollida, kas stringi algus vastab, ekstrakt:
match()
- Kontrollige, kas vasted ei piirdu algusega:
search()
- Kontrollida, kas kogu string vastab:
fullmatch()
- Hankige nimekiri kõikidest sobivatest osadest:
findall()
- Hangib kõik sobivad osad iteraatorina:
finditer()
- Asendage sobiv osa:
sub()
,subn()
- Stringide jagamine regulaaravaldiste mustritega:
split()
Pärast seda selgitan metamärke (erimärke) ja regulaaravaldiste erijada, mida saab kasutada re-moodulis. Põhimõtteliselt on tegemist standardse regulaaravaldise süntaksiga, kuid olge ettevaatlik lipukeste (eriti re.ASCII) seadistamisega.
- Regulaaravaldise metamärgid, erijärged ja hoiatused Pythonis
- Lipu seadmine
- Piiratud ASCII tähemärkidega:
re.ASCII
- Ei sõltu suur- ja väiketähtedest:
re.IGNORECASE
- Sobita iga rea algus ja lõpp:
re.MULTILINE
- Mitme lipu määramine
- Piiratud ASCII tähemärkidega:
- Ahned ja mitte-ahned matšid
- Regulaarse väljendi mustri koostamine: compile()
- mängu objekt
- Kontrollida, kas stringi algus vastab, väljavõte: match()
- Kontrollida vasteid, mis ei piirdu algusega, väljavõte: search()
- Kontrollida, kas kogu string vastab: fullmatch()
- Saada nimekiri kõikidest sobivatest osadest: findall()
- Hangi kõik sobivad osad iteraatorina: finditer()
- Asendage sobivad osad: sub(), subn()
- Stringide jagamine regulaaravaldiste mustritega: split()
- Regulaaravaldise metamärgid, erijärged ja hoiatused Pythonis
- Lipu seadmine
- Ahned ja mitte-ahned matšid
Regulaarse väljendi mustri koostamine: compile()
Re-moodulis on kaks võimalust regulaaravaldiste töötlemiseks.
Käivita koos funktsiooniga
Esimene on funktsioon.re.match()
,re.sub()
Sellised funktsioonid on saadaval ekstraheerimise, asendamise ja muude protsesside teostamiseks, kasutades regulaarseid väljendusmustreid.
Funktsioonide üksikasju kirjeldatakse hiljem, kuid kõigis neis on esimene argument regulaaravaldise mustri string, millele järgneb töödeldav string ja nii edasi. Näiteks re.sub(), mis teostab asendamise, teine argument on asendusstring ja kolmas argument on töödeldav string.
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
Pange tähele, et [a-z] selles näites tähendab regulaaravaldise mustris mis tahes märki alates a-st kuni z-ni (st väiketähestikku) ja + tähendab eelmise mustri (antud juhul [a-z]) kordamist üks või mitu korda. [a-z]+ sobib mis tahes stringiga, mis kordab ühte või mitut väikse tähestiku märki.
. on metamärk (erimärk, millel on eriline tähendus) ja seda tuleb vältida kaldkriipsu abil.
Kuna regulaaravaldiste mustri stringid kasutavad sageli palju kaldkriipsu, on mugav kasutada toorest stringi nagu näites.
Käib regulaarse väljendusmudeli objekti meetodis
Teine viis regulaaravaldiste töötlemiseks re-moodulis on regulaaravaldiste mustri objektimeetod.
Kasutades re.compile(), saate koostada regulaaravaldise mustri stringi, et luua regulaaravaldise mustri objekt.
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()
Näiteks võib sama protsessi nagu neid funktsioone täita regulaaravaldiste objektide meetoditega 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
Kõik allpool kirjeldatud re.xxx() funktsioonid on esitatud ka regulaaravaldise objekti meetoditena.
Kui te kordate protsessi, mis kasutab sama mustrit, on tõhusam genereerida regulaaravaldise objekt re.compile() abil ja kasutada seda ümberringi.
Järgnevas näidiskoodis kasutatakse funktsiooni mugavuse huvides ilma kompileerimiseta, kuid kui soovite sama mustrit korduvalt kasutada, on soovitatav see eelnevalt kompileerida ja käivitada see regulaaravaldise objekti meetodina.
mängu objekt
match(), search() jne. tagastavad vasteobjekti.
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'>
Sobitatud string ja positsioon saadakse järgmiste match-objekti meetodite abil.
- Hankige mängu asukoht:
start()
,end()
,span()
- Hangib sobiva stringi:
group()
- Hankige iga rühma jaoks string:
groups()
print(m.start())
# 0
print(m.end())
# 11
print(m.span())
# (0, 11)
print(m.group())
# aaa@xxx.com
Kui ümbritsete regulaaravaldise mustri osa stringi sisse sulgudega(), töödeldakse seda osa grupina. Sellisel juhul saab iga rühmale vastava osa stringi rühmade() abil tuplina kätte.
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')
Kontrollida, kas stringi algus vastab, väljavõte: match()
match() tagastab match-objekti, kui stringi algus vastab mustrile.
Nagu eespool mainitud, saab match-objekti kasutada sobiva alamstringi väljavõtmiseks või lihtsalt selle kontrollimiseks, kas vastavus on saavutatud.
match() kontrollib ainult algust. Kui alguses ei ole sobivat stringi, siis tagastab see 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
Kontrollida vasteid, mis ei piirdu algusega, väljavõte: search()
Nagu match(), tagastab see match-objekti, kui see vastab.
Kui on mitu kokkulangevat osa, tagastatakse ainult esimene kokkulangev osa.
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'>
Kui soovite saada kõik sobivad osad, kasutage findall() või finditer(), nagu allpool kirjeldatud.
Kontrollida, kas kogu string vastab: fullmatch()
Selleks, et kontrollida, kas kogu string vastab regulaaravaldise mustrile, kasutage funktsiooni fullmatch(). See on kasulik näiteks selleks, et kontrollida, kas string sobib e-posti aadressiks või mitte.
Kui kogu string vastab, tagastatakse match-objekt.
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'>
Kui on sobimatuid osi (ainult osaline kokkulangevus või ei ole üldse kokkulangevust), tagastatakse None.
s = '!!!aaa@xxx.com!!!'
m = re.fullmatch(r'[a-z]+@[a-z]+\.com', s)
print(m)
# None
Funktsioon fullmatch() lisati Python 3.4. Kui soovite sama teha ka varasemates versioonides, kasutage match() ja lõpus sobivat metamärki $. Kui kogu string algusest lõpuni ei vasta, siis tagastab see None.
s = '!!!aaa@xxx.com!!!'
m = re.match(r'[a-z]+@[a-z]+\.com$', s)
print(m)
# None
Saada nimekiri kõikidest sobivatest osadest: findall()
findall() tagastab kõigi sobivate alamsõnade loendi. Pange tähele, et nimekirja elemendid ei ole mitte vasteobjektid, vaid stringid.
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']
Vastavate osade arvu saab kontrollida, kasutades sisseehitatud funktsiooni len(), mis tagastab nimekirja elementide arvu.
print(len(result))
# 3
Sulgudega() rühmitamine regulaaravaldise mustris tagastab topelite loendi, mille elemendid on iga rühma stringid. See on samaväärne group() funktsiooniga match objektis.
result = re.findall(r'([a-z]+)@([a-z]+)\.([a-z]+)', s)
print(result)
# [('aaa', 'xxx', 'com'), ('bbb', 'yyy', 'com'), ('ccc', 'zzz', 'net')]
Grupi sulgudes () võib olla nested, nii et kui soovite saada ka kogu vastet, siis lihtsalt sulgege kogu vaste sulgudesse ().
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')]
Kui vastavust ei leita, tagastatakse tühi tupel.
result = re.findall('[0-9]+', s)
print(result)
# []
Hangi kõik sobivad osad iteraatorina: finditer()
finditer() tagastab kõik sobivad osad iteraatorina. Elemendid ei ole stringid nagu findall(), vaid vastavad objektid, nii et saad sobivate osade asukoha (indeksi).
Iteraatorit ennast ei saa print() abil välja trükkida, et saada selle sisu. Kui kasutate sisseehitatud funktsiooni next() või for-avaldust, saate sisu ükshaaval kätte.
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'>
Seda saab konverteerida list() abil ka loeteluks.
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)
Kui soovite saada kõigi kokkulangevate osade positsiooni, on loetelu mõistmise märkimine mugavam kui list().
print([m.span() for m in re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)])
# [(0, 11), (13, 24), (26, 37)]
Iteraator võtab elemendid välja järjekorras. Pange tähele, et kui püüate pärast lõppu veel elemente välja võtta, ei jää teil midagi alles.
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))
# []
Asendage sobivad osad: sub(), subn()
Kasutades sub(), saate sobitatud osa asendada teise stringiga. Tagastatakse asendatud string.
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'>
Sulgude() abil rühmitamisel saab sobitatud stringi kasutada asendatavas stringis.
Vaikimisi toetatakse järgmist: Pange tähele, et tavaliste stringide puhul, mis ei ole toorstringid, tuleb tagurpidi kaldkriipsu vältimiseks esitada tagurpidi kaldkriipsu ees.
\1 | Esimene sulgemine |
\2 | Teine sulgemine |
\3 | Kolmas sulgemine |
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>
Kui annate rühmale nime, kirjutades selle regulaaravaldise mustri sulgude algusesse, saate seda määrata numbri asemel nime kasutades, nagu allpool näidatud.\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
Argument count määrab asenduste maksimaalse arvu. Asendatakse ainult vasakpoolne arv.
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() tagastab tupli, mis koosneb asendatud stringist (sama, mis sub() tagastusväärtus) ja asendatud osade arvust (arv, mis vastas mustrile).
result = re.subn(r'[a-z]+@[a-z]+\.com', 'new-address', s)
print(result)
# ('new-address, new-address, ccc@zzz.net', 2)
Argumentide määramise meetod on sama nagu sub(). Võite kasutada sulgudes grupeeritud osa või määrata argumentide arvu.
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)
Stringide jagamine regulaaravaldiste mustritega: split()
split() jagab stringi selles osas, mis vastab mustrile, ja tagastab selle loeteluna.
Pange tähele, et esimene ja viimane kokkulangevus sisaldab tühja stringi tulemuseks oleva loendi alguses ja lõpus.
s = '111aaa222bbb333'
result = re.split('[a-z]+', s)
print(result)
# ['111', '222', '333']
result = re.split('[0-9]+', s)
print(result)
# ['', 'aaa', 'bbb', '']
Argument maxsplit määrab maksimaalse arvu jagamisi (tükke). Jagatakse ainult vasakpoolne arv.
result = re.split('[a-z]+', s, 1)
print(result)
# ['111', '222bbb333']
Regulaaravaldise metamärgid, erijärged ja hoiatused Pythonis
Peamised regulaaravaldise metamärgid (erimärgid) ja erijärjestused, mida saab kasutada Python 3 re moodulis, on järgmised
metatähis | sisu |
---|---|
. | mis tahes üksikmärk peale uue rea (sealhulgas uus rida koos DOTALL-märgiga) |
^ | stringi algus (vastab ka iga rea algusele, millel on MULTILINE lipukene) |
$ | Stringi lõpp (sobib ka iga rea lõppu MULTILINE lipukesega) |
* | Korda eelmist mustrit rohkem kui 0 korda. |
+ | Korrake eelmist mustrit vähemalt üks kord. |
? | Korda eelmist mustrit 0 või 1 korda. |
{m} | Korda eelmist mustrit m korda |
{m, n} | Viimane muster.m ~n kordus |
[] | Tähemärkide kogum[] Vastab ükskõik millisele neist märkidest |
| | VÕIA|B Vastab kas A- või B-mustrile |
spetsiaalne jada | sisu |
---|---|
\d | Unicode kümnendarvud (piiratud ASCII numbritega ASCII lipuga) |
\D | \d See tähendab vastupidist. |
\s | Unicode'i tühimärgid (ASCII lipuga piiratud ASCII tühimärkidega) |
\S | \s See tähendab vastupidist. |
\w | Unicode'i sõnamärgid ja allajooned (piiratud ASCII tähtnumbriliste tähemärkide ja allajoonega ASCII lipu järgi) |
\W | \w See tähendab vastupidist. |
Kõik need ei ole käesolevas tabelis loetletud. Täielik nimekiri on esitatud ametlikus dokumentatsioonis.
Pange tähele, et mõned tähendused on Python 2-s teistsugused.
Lipu seadmine
Nagu ülaltoodud tabelis näidatud, muudavad mõned metamärgid ja spetsiaalsed järjestused oma režiimi sõltuvalt lipust.
Siin on hõlmatud ainult peamised lipud. Ülejäänu kohta vaata ametlikku dokumentatsiooni.
Piiratud ASCII tähemärkidega: re.ASCII
\w
See sobib ka kahebaidiliste kanjide, tähtnumbriliste märkide jne jaoks vaikimisi Python 3 stringide puhul. See ei ole samaväärne, sest see ei ole standardne regulaaravaldis.[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
Kui te määrate igas funktsioonis argumendi lipudeks re.ASCII või lisate regulaaravaldise mustri stringi algusesse järgmise inline lipu, vastab see ainult ASCII-märkidele (see ei vasta kahebaidulistele jaapani tähtedele, tähtnumbrilistele märkidele jne).(?a)
Sellisel juhul on järgmised kaks samaväärsed.\w
=[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
Sama kehtib ka kompileerimisel re.compile() abil. Kasutage argumenti flags või inline flags.
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 on saadaval ka lühivormina re. A. Võite kasutada kas.
print(re.ASCII is re.A)
# True
\W, mis on \W vastand, on samuti mõjutatud re.ASCII ja inline lipukestest.
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'>
Nagu \w puhul, sobivad järgmised kaks vaikimisi nii ühe- kui ka kahebaidiliste märkidega, kuid piirduvad ühebaidiliste märkidega, kui on määratud re.ASCII või inline lipud.
- Sobita numbreid
\d
- Vastab tühjale kohale
\s
- Vastab muudele kui numbritele
\D
- Sobib mis tahes mitte-ruumiga.
\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
Ei sõltu suur- ja väiketähtedest:re.IGNORECASE
Vaikimisi on see suur- ja väiketähtede suhtes tundlik. Mõlema sobitamiseks peate musterisse lisama nii suur- kui ka väiketähti.
re.IGNORECASE
Kui see on määratud, siis vastab see tundmatuseni. Võrreldes standardsete regulaaravaldiste i lipuga.
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'>
Võite kasutada vähem või võrdne.
- inline-lipp
(?i)
- lühend
re.I
Sobita iga rea algus ja lõpp:re.MULTILINE
^
Selle regulaaravaldise metamärgid vastavad stringi algusele.
Vaikimisi sobitatakse ainult kogu stringi algus, kuid järgnevalt sobitatakse ka iga rea algus. Võrreldes m lipuga tavalistes regulaaravaldistes.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']
$
Sobib stringi lõppu. Vaikimisi sobitatakse ainult kogu stringi lõppu.re.MULTILINE
Kui te määrate selle, vastab see ka iga rea lõppu.
result = re.findall('[a-z]+$', s)
print(result)
# ['zzz']
result = re.findall('[a-z]+$', s, flags=re.MULTILINE)
print(result)
# ['xxx', 'yyy', 'zzz']
Võite kasutada vähem või võrdne.
- inline-lipp
(?m)
- lühend
re.M
Mitme lipu määramine
|
Kui soovite lubada korraga mitut lippu, kasutage seda. Inline-lippude puhul peab igale tähemärgile järgnema täht, nagu allpool näidatud.(?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']
Ahned ja mitte-ahned matšid
See on üldine probleem regulaaravaldiste puhul, mitte ainult Pythoni probleem, aga ma kirjutan sellest, sest see kipub mind hätta ajama.
Vaikimisi on järgmine ahne kokkulangevus, mis vastab pikimale võimalikule stringile.
*
+
?
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
Selle järel olev ? annab tulemuseks mitte-halva, minimaalse kokkulangevuse, mis vastab lühimale võimalikule stringile.
*?
+?
??
m = re.match(r'.+?com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
print(m.group())
# aaa@xxx.com
Pange tähele, et vaikimisi ahne kokkulangevus võib sobida ootamatute stringidega.