re – reguláris kifejezések

Itt egy nagyon részletes angol nyelvű leírás található a Python reguláris kifejezések használatáról

A reguláris kifejezésekkel mintákat adunk meg, és ellenőrizni tudjuk hogy egy adott szöveg illeszkedik-e a mintára (match függvény), illetve milyen illeszkedéseket tartalmaz (search függvény).

Adott mintára illeszkedések keresése – például egy weboldal forráskódjában

# File: re_minta_keresese.py #!/usr/bin/python import urllib2, re # cel: <a> tagok megkeresese. # FONTOS: pluszbeallitasok flag-ekkel igy lehetseges: # p=re.compile(regexp, re.DOTALL) ha a . az újsor karatkerre is vonatkozzon # re.DOTALL ugyanaz, mint re.S, nezd meg a reszletes angol leirast, compile flags. # tobbszoros flag beallitasa: # p=re.compile(regexp, re.DOTALL | re.IGNORECASE) grep karakter "OR"-nak felel meg. def regexp_kereses_szovegben(text, regexp): p = re.compile(regexp) result = p.findall(text) return result url="http://www.pressedefrance.com/" page_src = urllib2.urlopen(url).read() print regexp_kereses_szovegben(page_src, "<a.*?>")
# File: re_minta_keresese.out

['<a href="http://www.pressedefrance.com/presse/presse_francai
se/vente/journaux/vente_journaux/index.htm">', '<a href=&qu
ot;http://www.pressedefrance.com/presse/presse_francaise/journaux/arch
ives/archive_journaux/archive_journaux.htm">', '<a href=&qu
ot;http://www.pressedefrance.com/presse/presse_francaise/journaux/arch
ives/archive_journaux/index.htm">', 
... es a többi

Adott mintára illeszkedések cseréje:

Ha a regexp mintát nem lefordítva használod, az re modul átmenetileg eltárolja a mintádat, ezért kis programoknál nem szükséges a minták fordítása. Az átmeneti tár a 2.0-ás Python óta 100 lefordított regexp kifejezést tárol.

# File: re_szoveg_csere.py import re # cel: adott regularis kifejezesre illeszkedo talalatok lecserelese. # EZ A PELDA ELORE LEFORDITOTT MINTAT HASZNAL def csere(szoveg, regexp, erre_csereld=''): p = re.compile(regexp) return p.sub(erre_csereld, szoveg) szoveg = "Ma 2006 majus 19-e pentek van, esik az eso es reggel kimentem futni..." print csere(szoveg, "e.*?a", "XX") # ITT NEM HASZNALUNK ELORE LEFORDITOTT MINTAT # Minden nem betubol allo sorozatot egy kotojelle alakit print re.sub("[^\w]+", "-", szoveg) # Minden onallo szot atalakitunk print re.sub("\S+", "-SZO-", szoveg)
# File: re_szoveg_csere.out

Ma 2006 majus 19-XXn, XXz eso es reggel kimentem futni...
Ma-2006-majus-19-e-pentek-van-esik-az-eso-es-reggel-kimentem-futni-
-SZO- -SZO- -SZO- -SZO- -SZO- -SZO- -SZO- -SZO- -SZO- -SZO- -SZO- -SZO
- -SZO-

Példák a reguláris kifejezésekre:

# File: re_illeszkedesek_keresese.py import re text = "Attila a Hun megmutatja, egy pelda 2006-bol, 15 -en gepeltem be" # a match a karakterlanc elejere probal illeszkedni, kesobbi talalatokat NEM ad vissza. # repr(objektum) az objektum szoveges abrazolasaval ter vissza. print "szamjegykereses MINDEN KARAKTERLANC-RESZLETRE:" p = re.compile('\d+') talalt_szamjegyek = p.findall(text) print talalt_szamjegyek print "ezekben a poziciokban talalt szamjegyeket:" iterator = p.finditer(text) for illeszkedes in iterator: print illeszkedes.span() ################################################################ print # uressor print "a match csak a karakterlanc elejere illeszkedik, a vegerol nem ad vissza talalatot." # illeszkedes egy karakterre: '.' m = re.match(".", text) if m: print repr("."), "=>", repr(m.group(0)) # barmilyen karakterlancbol allo (leghosszabb) sorozatot keressuk, # ez gyakorlatilag a teljes szoveg m = re.match(".*", text) if m: print repr(".*"), "=>", repr(m.group(0)) # betukbol allo sorozatot keresunk (minimum egy betu) m = re.match("\w+", text) if m: print repr("\w+"), "=>", repr(m.group(0)) # szamjegyekbol allo karakterlancot keresunk m = re.match("\d+", text) if m: print repr("\d+"), "=>", repr(m.group(0)) else: print "nem volt szamjegy A KARAKTERLANC LEGELEJEN!" m = re.match("\d+", "22 " + text) if m: print repr("\d+"), "=>", repr(m.group(0)) print "most volt szamjegy a karakterlanc elejen!"
# File: re_illeszkedesek_keresese.out

szamjegykereses MINDEN KARAKTERLANC-RESZLETRE:
['2006', '15']
ezekben a poziciokban talalt szamjegyeket:
(35, 39)
(45, 47)
a match csak a karakterlanc elejere illeszkedik, a vegerol nem ad viss
za talalatot.
'.' => 'A'
'.*' => 'Attila a Hun megmutatja, egy pelda 2006-bol, 15 -en gepelt
em be'
'\\w+' => 'Attila'
nem volt szamjegy A KARAKTERLANC LEGELEJEN!
'\\d+' => '22'
most volt szamjegy a karakterlanc elejen!

A mintában zárójelekkel csoportokat hozhatsz létre. Ha a megadott minta illeszkedik, a group() metódussal hivatkozhatsz az egyes csoportokra. group(1) az első csoport tartalmával tér vissza, group(2) a másodikéval, és így tovább. Ha a group() -nak több csoport-számot adsz át, egy tupléval tér vissza.

Illeszkedő csoportok kiválasztása:

# File: re_illeszkedo_csoportok_kivalasztasa.py

import re

text ="10/15/99"

# itt keressuk a minta egyes reszeire tudunk hivatkozni. 
# az elso zarojel az elso, a masodik a masodik...
m = re.match("(\d{2})/(\d{2})/(\d{2,4})", text)
if m:
    print m.group(1, 2, 3) # hivatkozas a talalat egyes reszeire
    print "A nulladik csoport az eredeti talalat:", m.group(0)
    
print "Egymasba agyazott csoportositas:"
m = re.match("((\d{2})/(\d{2}))/(\d{2,4})", text)
if m:
    print m.group(1, 2, 3, 4)
# File: re_illeszkedo_csoportok_kivalasztasa.out

('10', '15', '99')
A nulladik csoport az eredeti talalat: 10/15/99
Egymasba agyazott csoportositas:
('10/15', '10', '15', '99')

A search függvény a karakterláncon belül keresi a mintát. A keresés balról jobbra történik, minden egyes karakterpozíciót érint – és az elsÅ‘ találattal visszatér. Ha nem talál a mintára illeszkedÅ‘ részletet, None értékkel tér vissza.

Keresés search-al

# File: re_kereses_search_al.py import re text = "Search pelda: itt van egy datum - 10/25/95 es !" print text m = re.search("(\d{1,2})/(\d{1,2})/(\d{2,4})", text) print m.group(1), m.group(2), m.group(3) month, day, year = m.group(1, 2, 3) print month, day, year date = m.group(0), "a nulladik elem a teljes talalatot tartalmazza" print date print "="*20 ########################################### # kiserletezes, mi tortenik ha tobb talalat is lehetseges? text = "szamok: 23, 45, 65, 12, 93" print text m = re.search("\d{1,2}", text) print m.group(0)
# File: re_kereses_search_al.out

Search pelda: itt van egy datum - 10/25/95 es !
10 25 95
10 25 95
('10/25/95', 'a nulladik elem a teljes talalatot tartalmazza')
====================
szamok: 23, 45, 65, 12, 93
23

Mi a különbség az re.search() és az re.match() között?

search() és match() összehasonlítása

A match() csak akkor találja meg az eredményt, ha az a karakterlánc elején van. A search() bárhol megtalálja, de csak az első elemmel tér vissza. A különbségnek teljesítménybeli okai vannak, a fenti megszorításokkal gyorsabb a keresés. Ha rész-karakterláncokból is szükség van a találatokra, a findall()-t használd!

# File: re_search_match_osszehasonlitasa.py

>>> print re.match("alma", "almasalata").span()
(0, 4)
>>> print re.match("alma", "vadalma")
None
>>> p.findall("vadalma alomba vagy kupacba szedva hallgatag halak modjara hallgat.")
['adalma alomba vagy kupacba szedva hallgatag halak modjara hall']

>>> p = re.compile("a.*?l")  # fontos: a kerdojel miatt a legkisebb illeszkedeseket keresi!

>>> p.findall("vadalma alomba vagy kupacba szedva hallgatag halak modjara hallgat.")
['adal', 'a al', 'a vagy kupacba szedva hal', 'atag hal', 'ak modjara hal']

Post Comments

You must be logged in to post a comment.