2.36. Grupe i sidra¶
Uzorak može učiniti više od pukog „ovaj niz odgovara” – može razdvojiti podudarane dijelove i predati svaki od njih aplikaciji po imenu. Zagrade oko dijela uzorka pretvaraju ga u grupu za hvatanje; objekt podudaranja zatim svaku grupu izlaže kao zaseban podniz.
2.36.1. Grupe za hvatanje¶
Omotajte bilo koji dio uzorka u (...) da uhvatite ono čemu odgovara:
>>> import re
>>> m = re.search(r'temp (\d+) at (\d+)s', 'temp 42 at 137s ok')
>>> m.group(0)
'temp 42 at 137s'
>>> m.group(1)
'42'
>>> m.group(2)
'137'
Grupa 0 uvijek je cijelo podudaranje.
Grupe 1, 2, … su uhvaćeni podnizovi, numerirani slijeva nadesno prema svojoj otvarajućoj zagradi.
Pozivanje
match.group()s indeksom iza posljednje grupe bacaIndexError.
Uobičajen je obrazac „podudari poznatu strukturu, uhvati promjenjive dijelove kao cijele brojeve”:
def parse_temp(line):
m = re.search(r'temp (\d+) at (\d+)s', line)
if not m:
return None
return int(m.group(1)), int(m.group(2))
2.36.2. Grupe bez hvatanja¶
Zagrade također grupiraju podizraz tako da se kvantifikator može primijeniti na cijelu grupu. To je jedina svrha grupiranja u r'(ab)+' – „jedan ili više ab„. Činjenica da se ab pojavljuje kao grupa 1 nuspojava je.
Za grupiranje bez hvatanja koristite (?:...)
>>> re.search(r'(?:ab)+', 'xababy').group(0)
'abab'
Grupe bez hvatanja održavaju brojeve grupa urednima kad uzorak koristi grupiranje radi strukture, ali ne mari za izdvajanje svakog dijela.
2.36.3. Sidra¶
Sidra ne podudaraju znak – podudaraju poziciju.
^– početak niza.$– kraj niza.
Sidra su ono što čini da se re.match() i re.search() ponašaju različito. re.match(p, s) isto je kao re.search('^' + p, s): prisiljava uzorak da počne na poziciji 0. Dodavanje $ na kraj uzorka zatim čini da uzorak podudara cijeli niz i ništa drugo:
>>> re.search(r'^\d+$', '12345')
<match num=1>
>>> re.search(r'^\d+$', '12345 ok') is None
True
^ i $ u MicroPython modulu re uvijek znače početak i kraj cijelog niza proslijeđenog u re.search(). Ne postoji re.MULTILINE zastavica koja bi ih natjerala da se podudaraju na svakom ugrađenom prijelomu retka, a $ ne podudara ni poziciju ispred završnog \n – mora biti apsolutni kraj ulaza. Za ponašanje po retku, najprije podijelite ulaz po prijelomima retka i pokrenite uzorak na svakom retku.
2.36.4. Skupovi znakova¶
Uglate zagrade definiraju eksplicitan skup znakova. Podudaranje troši točno jedan znak iz skupa.
[abc]– jedan oda,b,c.[a-z]– jedan znak u rasponua-z(uključivo).[a-zA-Z0-9]– slova ili znamenke. Tri raspona kombinirana.[^abc]– ne jedan oda,b,c. Znak^negira samo kad je prvi znak unutar zagrada.
Primjeri:
>>> re.search(r'[A-F0-9]{6}', 'colour #1a2b3c rest').group(0)
'1A2B3C'
>>> re.search(r'[A-F0-9]{6}', 'colour #1a2b3c rest') is None
True
Prvi poziv u praksi vraća None jer je doslovni tekst u malim slovima. MicroPython modul re nema re.IGNORECASE zastavicu – za podudaranje neovisno o veličini slova, upišite oba oblika u skup:
>>> re.search(r'[A-Fa-f0-9]{6}', 'colour #1a2b3c rest').group(0)
'1a2b3c'
Kratice klasa (\d, \s, \w i njihovi negirani oblici) mogu se koristiti i unutar [...]: [\w-] znači „znakovi riječi ili doslovna crtica”.
2.36.5. Pohlepni naspram lijenih kvantifikatora¶
Kvantifikatori *, +, ? i {m,n} prema zadanom su pohlepni – podudaraju onoliko znakova koliko će ostatak uzorka i dalje dopustiti. Često je to upravo ono što se želi; ponekad nije:
>>> re.search(r'<(.+)>', 'a <b> <c> d').group(1)
'b> <c'
Pohlepni .+ zgrabio je sve do posljednjeg >. Dodavanjem ? kvantifikator postaje lijen – podudara što je manje moguće:
>>> re.search(r'<(.+?)>', 'a <b> <c> d').group(1)
'b'
Lijeni oblik staje na prvom >. Lijeni kvantifikatori stalno se pojavljuju pri izdvajanju uravnoteženih graničnika iz niza.
2.36.6. Povratne reference u zamjeni¶
re.sub() može se u zamjenskom nizu pozvati natrag na uhvaćene grupe putem \1, \2, … Zamjena prepisuje svako podudaranje koristeći uhvaćene dijelove:
>>> re.sub(r'(\d+)\.(\d+)', r'\2.\1', 'swap 12.34 and 5.6')
'swap 34.12 and 6.5'
Svako podudaranje hvata dva broja, a zamjena ih izmjenjuje. \g<1> je alternativna sintaksa za istu stvar – korisna kad je sljedeći znak u zamjeni znamenka (r'\g<1>0' da se grupi 1 dometne doslovna nula, umjesto čitanja „grupa 10”).
2.36.7. Što nije dostupno¶
Podsjetnik na ono što MicroPython modul re ne podržava, za slučaj da ovdje doluta uzorak iz CPythona i iznenadi vas:
Pogled unaprijed
(?=...)i pogled unatrag(?<=...)– nisu implementirani.Imenovane grupe
(?P<name>...)i imenovane povratne reference(?P=name)– nisu implementirane.Konstante zastavica poput
re.IGNORECASE,re.MULTILINE,re.DOTALL– ne uvažavaju se. Izgradite skup neovisan o veličini slova ili sami unaprijed podijelite ulaz.Metode
match.groups(),match.span(),match.start()imatch.end()ograničene su na ROM razinu koju nijedna isporučena OpenMV ploča ne omogućuje. Kod koji se oslanja na njih neće se izvoditi na kameri.
S uzorcima, grupama i sidrima, skup regex alata na kameri dovoljno je malen da se nauči u jednom sjedenju i dovoljno bogat da obavi sve osim kontekstno osjetljivog parsiranja.