Pythonin säännöllisen lausekemoduulin re käyttäminen (match, search, sub jne.)

liiketoiminta

Säännöllisten lausekkeiden käsittelyyn Pythonissa käytetään standardikirjaston re-moduulia. Sen avulla voit poimia, korvata ja jakaa merkkijonoja säännöllisten lausekkeiden mallien avulla.

Tässä osassa selitetään ensin re-moduulin toiminnot ja menetelmät.

  • Säännöllisten lausekkeiden kokoaminen:compile()
  • match-objekti
  • Tarkista, täsmääkö merkkijonon alku, poimi:match()
  • Tarkista ottelut, jotka eivät rajoitu alkuun:search()
  • Tarkista, täsmääkö koko merkkijono:fullmatch()
  • Hanki luettelo kaikista vastaavista osista:findall()
  • Hae kaikki vastaavat osat iteraattorina:finditer()
  • Vaihda vastaava osa:sub(),subn()
  • Merkkijonojen jakaminen säännöllisillä lausekkeilla:split()

Tämän jälkeen selitän metamerkit (erikoismerkit) ja säännöllisten lausekkeiden erikoisjaksot, joita voidaan käyttää re-moduulissa. Periaatteessa kyseessä on tavallinen säännöllisen lausekkeen syntaksi, mutta ole varovainen lippujen asettamisessa (erityisesti re.ASCII).

  • Säännöllisten lausekkeiden metamerkit, erikoisjaksot ja varoitukset Pythonissa
  • Lipun asettaminen
    • Rajoitettu ASCII-merkkeihin:re.ASCII
    • Isoja ja pieniä kirjaimia ei oteta huomioon:re.IGNORECASE
    • Yhdistä kunkin rivin alku ja loppu:re.MULTILINE
    • Määritä useita lippuja
  • Ahneet ja ei-ahneet ottelut

Kokoa säännöllisen lausekkeen kuvio: compile()

Re-moduulissa on kaksi tapaa suorittaa säännöllisten lausekkeiden käsittely.

Suorita toiminnon kanssa

Ensimmäinen on funktio.re.match(),re.sub()Tämänkaltaiset funktiot ovat käytettävissä poiminnan, korvaamisen ja muiden prosessien suorittamiseen säännöllisten lausekkeiden avulla.

Funktioiden yksityiskohdat kuvataan myöhemmin, mutta kaikissa niissä ensimmäinen argumentti on säännöllisen lausekkeen kuvion merkkijono, jota seuraa käsiteltävä merkkijono ja niin edelleen. Esimerkiksi re.sub()-funktiossa, joka suorittaa korvaamisen, toinen argumentti on korvausmerkkijono ja kolmas argumentti on käsiteltävä merkkijono.

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

Huomaa, että [a-z] tarkoittaa tässä esimerkissä säännöllisen lausekkeen kuviossa mitä tahansa merkkiä a:sta z:hen (eli pienaakkosia), ja + tarkoittaa edellisen kuvion (tässä tapauksessa [a-z]) toistamista yhden tai useamman kerran. [a-z]+ vastaa mitä tahansa merkkijonoa, jossa toistuu yksi tai useampi pieni aakkosmerkki.

. on metamerkki (merkki, jolla on erityinen merkitys), ja se on vältettävä backslashilla.

Koska säännöllisen lausekkeen mallimerkkijonot käyttävät usein paljon vinoviivoja, on kätevää käyttää raakamerkkejä kuten esimerkissä.

Suoritetaan säännöllisen lausekkeen kuvio-objektin metodissa.

Toinen tapa käsitellä säännöllisiä lausekkeita re-moduulissa on säännöllisen lausekkeen kuvio-objektimenetelmä.

Käyttämällä re.compile() voit kääntää säännöllisen lausekkeen merkkijonon luodaksesi säännöllisen lausekkeen kuvioobjektin.

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()Sama prosessi kuin nämä funktiot voidaan suorittaa esimerkiksi säännöllisen lausekkeen objektien metodeina 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

Kaikki alla kuvatut re.xxx()-funktiot tarjotaan myös säännöllisen lausekkeen metodeina.

Jos toistat prosessia, jossa käytetään samaa kaavaa, on tehokkaampaa luoda säännöllisen lausekkeen objekti komennolla re.compile() ja käyttää sitä ympäriinsä.

Seuraavassa esimerkkikoodissa funktiota käytetään yksinkertaisuuden vuoksi ilman kääntämistä, mutta jos haluat käyttää samaa mallia toistuvasti, on suositeltavaa kääntää se etukäteen ja suorittaa se säännöllisen lausekkeen objektin metodina.

match-objekti

match(), search() jne. palauttavat match-olion.

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'>

Sovitettu merkkijono ja sijainti saadaan käyttämällä seuraavia match-olion metodeja.

  • Hae ottelun sijainti:start(),end(),span()
  • Hae sovitettu merkkijono:group()
  • Hae kunkin ryhmän merkkijono:groups()
print(m.start())
# 0

print(m.end())
# 11

print(m.span())
# (0, 11)

print(m.group())
# aaa@xxx.com

Jos suljet säännöllisen lausekkeen osan merkkijonoon sulkeilla(), osa käsitellään ryhmänä. Tällöin kunkin ryhmän kanssa täsmäävän osan merkkijono saadaan groups()-oliossa tuplina.

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')

Tarkista, täsmääkö merkkijonon alku, ote: match()

match() palauttaa match-olion, jos merkkijonon alku vastaa mallia.

Kuten edellä mainittiin, match-oliota voidaan käyttää täsmäävän osajonon poimimiseen tai yksinkertaisesti sen tarkistamiseen, löytyikö täsmäävä merkkijono.

match() tarkistaa vain alun. Jos alussa ei ole vastaavaa merkkijonoa, se palauttaa 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

Tarkista osumat, jotka eivät rajoitu vain alkuun, ote: search()

Kuten match(), se palauttaa match-olion, jos se täsmää.

Jos vastaavia osia on useita, vain ensimmäinen vastaava osa palautetaan.

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'>

Jos haluat saada kaikki vastaavat osat, käytä findall()- tai finditer()-toimintoa, kuten alla on kuvattu.

Tarkista, täsmääkö koko merkkijono: fullmatch()

Jos haluat tarkistaa, että koko merkkijono vastaa säännöllisen lausekkeen mallia, käytä fullmatch() -toimintoa. Tästä on hyötyä esimerkiksi tarkistettaessa, onko merkkijono kelvollinen sähköpostiosoitteeksi vai ei.

Jos koko merkkijono täsmää, match-olio palautetaan.

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'>

Jos osia ei löydy (vain osittaisia osumia tai ei osumia lainkaan), palautetaan None.

s = '!!!aaa@xxx.com!!!'

m = re.fullmatch(r'[a-z]+@[a-z]+\.com', s)
print(m)
# None

Fullmatch() lisättiin Python 3.4:ssä. Jos haluat tehdä saman aikaisemmissa versioissa, käytä match()-funktiota ja lopussa vastaavaa metamerkkiä $. Jos koko merkkijono alusta loppuun ei täsmää, se palauttaa None.

s = '!!!aaa@xxx.com!!!'

m = re.match(r'[a-z]+@[a-z]+\.com$', s)
print(m)
# None

Hae luettelo kaikista vastaavista osista: findall()

findall() palauttaa luettelon kaikista vastaavista merkkijonoista. Huomaa, että listan elementit eivät ole täsmääviä objekteja vaan merkkijonoja.

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']

Vastaavien osien lukumäärä voidaan tarkistaa käyttämällä sisäänrakennettua funktiota len(), joka palauttaa listan elementtien lukumäärän.

print(len(result))
# 3

Ryhmittely säännöllisen lausekkeen kuvion sulkeilla() palauttaa listan monisteista, joiden elementit ovat kunkin ryhmän merkkijonoja. Tämä vastaa group()-asetusta match-oliossa.

result = re.findall(r'([a-z]+)@([a-z]+)\.([a-z]+)', s)
print(result)
# [('aaa', 'xxx', 'com'), ('bbb', 'yyy', 'com'), ('ccc', 'zzz', 'net')]

Ryhmäsulkeet () voivat olla sisäkkäisiä, joten jos haluat saada myös koko ottelun, sulje koko ottelu sulkeisiin ().

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')]

Jos vastaavuutta ei löydy, palautetaan tyhjä tuple.

result = re.findall('[0-9]+', s)
print(result)
# []

Hae kaikki vastaavat osat iteraattorina: finditer()

finditer() palauttaa kaikki vastaavat osat iteraattorina. Elementit eivät ole merkkijonoja kuten findall(), vaan täsmääviä objekteja, joten voit saada täsmäävien osien sijainnin (indeksin).

Itse iteraattoria ei voi tulostaa print()-ohjelmalla sen sisällön saamiseksi. Jos käytät sisäänrakennettua funktiota next() tai for-lauseketta, voit saada sisällön yksitellen.

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'>

Se voidaan myös muuntaa listaksi komennolla 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)

Jos haluat saada kaikkien vastaavien osien sijainnin, list comprehension-notaatio on kätevämpi kuin list().

print([m.span() for m in re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)])
# [(0, 11), (13, 24), (26, 37)]

Iteraattori ottaa elementit järjestyksessä. Huomaa, että jos yrität poimia lisää elementtejä sen jälkeen, kun olet päässyt loppuun, sinulle ei jää mitään.

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))
# []

Korvaa vastaavat osat: sub(), subn()

Käyttämällä sub() voit korvata sovitetun osan toisella merkkijonolla. Korvattu merkkijono palautetaan.

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'>

Kun ryhmitellään sulkujen() avulla, sovitettua merkkijonoa voidaan käyttää korvattavassa merkkijonossa.

Oletusarvoisesti tuetaan seuraavia toimintoja: Huomaa, että tavallisissa merkkijonoissa, jotka eivät ole raakamerkkijonoja, backslash on lueteltava ennen backslash-viivaa, jotta backslash voidaan välttää.

\1Ensimmäinen sulku
\2Toinen sulku
\3Kolmas sulku
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>
Jos nimeät ryhmän kirjoittamalla sen säännöllisen lausekkeen kuvion sulkujen alkuun, voit määrittää sen käyttämällä nimeä numeron sijasta, kuten alla näkyy.
\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

Argumentti count määrittää korvausten enimmäismäärän. Vain vasemmalla puolella oleva määrä korvataan.

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() palauttaa tuplan, joka koostuu korvatusta merkkijonosta (sama kuin sub():n palautusarvo) ja korvattujen osien lukumäärästä (määrä, joka vastaa mallia).

result = re.subn(r'[a-z]+@[a-z]+\.com', 'new-address', s)
print(result)
# ('new-address, new-address, ccc@zzz.net', 2)

Argumenttien määritystapa on sama kuin sub():ssa. Voit käyttää sulkuihin ryhmiteltyä osaa tai määrittää argumenttien lukumäärän.

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)

Merkkijonojen jakaminen säännöllisillä lausekkeilla: split()

split() jakaa merkkijonon sen osan kohdalta, joka vastaa mallia, ja palauttaa sen listana.

Huomaa, että ensimmäinen ja viimeinen osuma sisältävät tyhjiä merkkijonoja tuloksena olevan luettelon alussa ja lopussa.

s = '111aaa222bbb333'

result = re.split('[a-z]+', s)
print(result)
# ['111', '222', '333']

result = re.split('[0-9]+', s)
print(result)
# ['', 'aaa', 'bbb', '']

Maxsplit-argumentti määrittää jakojen (palojen) enimmäismäärän. Vain vasemmanpuoleinen määrä jaetaan.

result = re.split('[a-z]+', s, 1)
print(result)
# ['111', '222bbb333']

Säännöllisten lausekkeiden metamerkit, erikoisjaksot ja varoitukset Pythonissa

Tärkeimmät säännöllisten lausekkeiden metamerkit (erikoismerkit) ja erikoisjaksot, joita voidaan käyttää Python 3 re -moduulissa, ovat seuraavat

metahahmosisältö
.Mikä tahansa muu yksittäinen merkki kuin uusi rivi (mukaan lukien uusi rivi, jossa on DOTALL-merkki).
^Merkkijonon alku (vastaa myös jokaisen rivin alkua, jossa on MULTILINE-merkki).
$Merkkijonon loppu (vastaa myös jokaisen rivin loppua, jossa on MULTILINE-merkki).
*Toista edellinen kuvio yli 0 kertaa.
+Toista edellinen kuvio vähintään kerran.
?Toista edellinen kuvio 0 tai 1 kertaa.
{m}Toista edellinen kuvio m kertaa
{m, n}Viimeinen kuvio.m~ntoista
[]Joukko merkkejä[]Sopii johonkin näistä merkeistä
|TAIA|BSopii joko A- tai B-kuvioon
erityinen sekvenssisisältö
\dUnicode-desimaaliluvut (rajoitettu ASCII-lukuihin ASCII-merkillä)
\D\dTarkoittaa tämän vastakohtaa.
\sUnicode-välimerkit (rajoitettu ASCII-välimerkillä ASCII-välimerkkeihin)
\S\sTarkoittaa tämän vastakohtaa.
\wUnicode-sanamerkit ja alleviivaukset (rajoitettu ASCII-merkillä ASCII-aakkosnumeerisiin merkkeihin ja alleviivauksiin).
\W\wTarkoittaa tämän vastakohtaa.

Kaikkia niistä ei ole lueteltu tässä taulukossa. Katso täydellinen luettelo virallisesta dokumentaatiosta.

Huomaa myös, että jotkut merkitykset ovat erilaisia Python 2:ssa.

Lipun asettaminen

Kuten yllä olevasta taulukosta käy ilmi, joidenkin metamerkkien ja erikoisjaksojen tila muuttuu lipun mukaan.

Tässä käsitellään vain tärkeimpiä lippuja. Katso loput virallisesta dokumentaatiosta.

Rajoitettu ASCII-merkkeihin: re.ASCII

\wTämä vastaa myös kaksitavuisia kanjeja, aakkosnumeerisia merkkejä jne. oletusarvoisesti Python 3 -merkkijonoissa. Se ei vastaa seuraavaa, koska se ei ole tavallinen säännöllinen lauseke.[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

Jos määrität re.ASCII:n kunkin funktion argumenttilippujen joukkoon tai lisäät seuraavan inline-lipputunnisteen säännöllisen lausekkeen merkkijonon alkuun, se vastaa vain ASCII-merkkejä (se ei vastaa kaksitavuisia japanilaisia merkkejä, aakkosnumeerisia merkkejä jne.).
(?a)
Tässä tapauksessa seuraavat kaksi vastaavat toisiaan.
\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 pätee käännettäessä komennolla re.compile(). Käytä argumenttia flags tai 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 saatavilla myös lyhyenä muotona re. A. Voit käyttää joko.

print(re.ASCII is re.A)
# True

\W, joka on \W:n vastakohta, vaikuttaa myös re.ASCII- ja inline-lippuihin.

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'>

Kuten \w, seuraavat kaksi vastaavat oletusarvoisesti sekä yhden että kahden tavun merkkejä, mutta ne rajoittuvat vain yhden tavun merkkeihin, jos re.ASCII- tai inline-merkki on määritetty.

  • Täsmää numerot\d
  • Sopii tyhjään tilaan\s
  • Sopii muihin kuin numeroihin\D
  • Sopii mihin tahansa muuhun kuin välilyöntiin.\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

Isoja ja pieniä kirjaimia ei oteta huomioon:re.IGNORECASE

Oletusarvoisesti se on isojen ja pienten kirjainten erotteleva. Jos haluat löytää molempia, sinun on sisällytettävä kuvioon sekä isoja että pieniä kirjaimia.

re.IGNORECASEJos tämä on määritetty, se täsmää tapauksesta riippumatta. Vastaa tavallisten säännöllisten lausekkeiden i-lippua.

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'>

Voit käyttää alle tai yhtä suuri kuin.

  • rivilippu(?i)
  • lyhennere.I

Yhdistä kunkin rivin alku ja loppu:re.MULTILINE

^Tämän säännöllisen lausekkeen metamerkit vastaavat merkkijonon alkua.

Oletusarvoisesti vain koko merkkijonon alku sovitetaan, mutta seuraava sovittaa myös jokaisen rivin alun. Vastaa tavallisten säännöllisten lausekkeiden m-lippua.
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']

$Täsmää merkkijonon loppuun. Oletusarvoisesti vain koko merkkijonon loppu sovitetaan.
re.MULTILINEJos määrität tämän, se vastaa myös jokaisen rivin loppua.

result = re.findall('[a-z]+$', s)
print(result)
# ['zzz']

result = re.findall('[a-z]+$', s, flags=re.MULTILINE)
print(result)
# ['xxx', 'yyy', 'zzz']

Voit käyttää alle tai yhtä suuri kuin.

  • rivilippu(?m)
  • lyhennere.M

Määritä useita lippuja

|Jos haluat ottaa käyttöön useita lippuja samanaikaisesti, käytä tätä. Kun kyseessä ovat riviin sijoitetut liput, jokaista merkkiä on seurattava kirjain, kuten alla on esitetty.
(?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']

Ahneet ja ei-ahneet ottelut

Tämä on yleinen ongelma säännöllisten lausekkeiden kanssa, ei vain Pythonin ongelma, mutta kirjoitan siitä, koska sillä on tapana aiheuttaa minulle ongelmia.

Oletusarvoisesti seuraava on ahne ottelu, joka vastaa pisintä mahdollista merkkijonoa.

  • *
  • +
  • ?
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

Sen perässä oleva ? johtaa ei-ahneeseen, minimaaliseen täsmäämiseen, joka vastaa lyhintä mahdollista merkkijonoa.

  • *?
  • +?
  • ??
m = re.match(r'.+?com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(m.group())
# aaa@xxx.com

Huomaa, että oletusarvoinen ahne ottelu voi osua odottamattomiin merkkijonoihin.

Copied title and URL