2.36. Csoportok és horgonyok¶
A minta többet is tehet annál, mint hogy kimondja: „ez a szöveg illeszkedik” – szét tudja szedni az illeszkedő darabokat, és név szerint át tudja adni mindegyiket az alkalmazásnak. A minta egy részét körülvevő zárójelek azt rögzítő csoporttá (capturing group) teszik; az illeszkedési objektum ekkor minden csoportot külön részszövegként tesz elérhetővé.
2.36.1. Rögzítő csoportok¶
A minta bármely részét tedd (...) zárójelek közé, hogy rögzítsd, amire illeszkedett:
>>> 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'
A 0. csoport mindig a teljes illeszkedés.
Az 1., 2., … csoportok a rögzített részszövegek, balról jobbra a nyitó zárójelük szerint sorszámozva.
Ha a
match.group()metódust az utolsó csoporton túli indexszel hívod meg,IndexErrorkeletkezik.
Gyakori minta a „illeszkedj egy ismert szerkezetre, és rögzítsd a változó részeket egészként”:
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. Nem rögzítő csoportok¶
A zárójelek egy részkifejezést is csoportosítanak, hogy egy kvantor az egész csoportra alkalmazható legyen. Az r'(ab)+' mintában a csoportosításnak ez az egyetlen célja – „egy vagy több ab„. Az, hogy az ab az 1. csoportként jelenik meg, mellékhatás.
Csoportosításhoz rögzítés nélkül használd a (?:...) formát:
>>> re.search(r'(?:ab)+', 'xababy').group(0)
'abab'
A nem rögzítő csoportok rendben tartják a csoportszámokat, amikor egy minta szerkezeti célból használ csoportosítást, de nem érdekli az egyes darabok kinyerése.
2.36.3. Horgonyok¶
A horgonyok nem egy karakterre illeszkednek – hanem egy pozícióra.
^– a szöveg eleje.$– a szöveg vége.
A horgonyok teszik eltérővé a re.match() és a re.search() viselkedését. Az re.match(p, s) ugyanaz, mint az re.search('^' + p, s): arra kényszeríti a mintát, hogy a 0. pozíciónál kezdődjön. A minta végéhez egy $ hozzáadása ezután azt eredményezi, hogy a minta a teljes szövegre illeszkedik és semmi másra:
>>> re.search(r'^\d+$', '12345')
<match num=1>
>>> re.search(r'^\d+$', '12345 ok') is None
True
A MicroPython re moduljában a ^ és a $ mindig a re.search() függvénynek átadott teljes szöveg elejét és végét jelenti. Nincs re.MULTILINE jelző, amely minden beágyazott sortörésnél illeszkedésre késztetné őket, és a $ nem illeszkedik egy záró \n előtti pozícióra sem – a bemenet abszolút végének kell lennie. Soronkénti viselkedéshez először bontsd fel a bemenetet sortörések mentén, és futtasd a mintát minden egyes soron.
2.36.4. Karakterhalmazok¶
A szögletes zárójelek karakterek explicit halmazát definiálják. Az illeszkedés pontosan egy karaktert fogyaszt el a halmazból.
[abc]– aza,b,cegyike.[a-z]– egy karakter aza-ztartományban (a határokat is beleértve).[a-zA-Z0-9]– betűk vagy számjegyek. Három tartomány kombinálva.[^abc]– nem aza,b,cegyike. A^csak akkor tagad, ha a zárójeleken belüli első karakter.
Példák:
>>> 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
Az első hívás a gyakorlatban None értéket ad vissza, mert a literális szöveg kisbetűs. A MicroPython re moduljának nincs re.IGNORECASE jelzője – a kis- és nagybetűt nem megkülönböztető illeszkedéshez írd be mindkét esetet a halmazba:
>>> re.search(r'[A-Fa-f0-9]{6}', 'colour #1a2b3c rest').group(0)
'1a2b3c'
Az osztály-rövidítések (\d, \s, \w és tagadott formáik) a [...] belsejében is használhatók: a [\w-] jelentése „szóalkotó karakterek vagy egy literális kötőjel”.
2.36.5. Mohó és lusta kvantorok¶
A *, +, ? és {m,n} kvantorok alapértelmezetten mohók – annyi karakterre illeszkednek, amennyit a minta többi része még megenged. Gyakran pontosan erre van szükség; néha viszont nem:
>>> re.search(r'<(.+)>', 'a <b> <c> d').group(1)
'b> <c'
A mohó .+ egészen az utolsó > jelig mindent megragadott. Egy ? hozzáfűzése a kvantort lustává teszi – a lehető legkevesebbre illeszkedik:
>>> re.search(r'<(.+?)>', 'a <b> <c> d').group(1)
'b'
A lusta forma az első > jelnél megáll. A lusta kvantorok állandóan előkerülnek, amikor kiegyensúlyozott elválasztók közötti tartalmat nyersz ki egy szövegből.
2.36.6. Visszahivatkozások a helyettesítésben¶
A re.sub() a helyettesítő szövegben a \1, \2, … formán keresztül visszahivatkozhat a rögzített csoportokra. A helyettesítés minden illeszkedést a rögzített darabok felhasználásával ír át:
>>> re.sub(r'(\d+)\.(\d+)', r'\2.\1', 'swap 12.34 and 5.6')
'swap 34.12 and 6.5'
Minden illeszkedés két számot rögzít, és a helyettesítés felcseréli őket. A \g<1> ugyanennek egy alternatív szintaxisa – akkor hasznos, ha a helyettesítésben a következő karakter egy számjegy (az r'\g<1>0' egy literális nullát fűz az 1. csoporthoz, ahelyett hogy a „10. csoportként” olvasná).
2.36.7. Mi nem áll rendelkezésre¶
Emlékeztető arról, mit nem támogat a MicroPython re modulja, arra az esetre, ha egy CPython-ból származó minta kerül ide, és meglep:
Előretekintés
(?=...)és visszatekintés(?<=...)– nincs megvalósítva.Nevesített csoportok
(?P<name>...)és nevesített visszahivatkozások(?P=name)– nincs megvalósítva.Olyan jelzőkonstansok, mint az
re.IGNORECASE,re.MULTILINE,re.DOTALL– nincsenek figyelembe véve. A kis- és nagybetűt nem megkülönböztető halmazt magad építsd fel, vagy magad bontsd fel előre a bemenetet.A
match.groups(),match.span(),match.start()ésmatch.end()metódusok olyan ROM-szinthez vannak kötve, amelyet egyetlen szállított OpenMV panel sem engedélyez. Az ezekre támaszkodó kód nem fog futni a kamerán.
A mintákkal, csoportokkal és horgonyokkal a kamerán elérhető regex-eszközkészlet elég kicsi ahhoz, hogy egy ülésben megtanulható legyen, és elég gazdag ahhoz, hogy a kontextusérzékeny elemzésen kívül mindent megoldjon.