Regulárne výrazy

Porovnanie :: PHP | Perl

Python pre prácu s regulárnymi výrazmi nezavádza žiadnu novú syntax, ale rieši to pomocou použitia modulov. Tento modul sa volá re a obsahuje niekoľko funkcií a konštánt, ktoré sú užitočné pre prácu s týmito výrazmi. Modul re používa regulárne výrazy v štýle jazyka Perl.

Python používa, tak ako aj Perl, nasledujúcu množinu znakov.

Výber znakov Význam Trieda znakov Perl
[0-9] Čísla 0 až 9 \d
[^0-9] Všetko ostatné okrem číslic \D
[ \f\n\r\t] Prázdny znak \s
[^ \f\n\r\t] Neprázdny znak \S
[a-zA-Z0-9] Alfanumerický znak \w
[^a-zA-Z0-9] Nealfanumerický znak \W

Jednou z dôležitých funkcií modulu re je funkcia re.match(). ktorá má dva argumenty - regulárny výraz a reťazec. Ak znaky na začiatku reťazca zodpovedajú regulárnemu výrazu, vráti objekt, ktorý umožňuje získať ďalšie informácie o výsledku, ak nezodpovedajú, tak vráti None.

// premenná cislo môže byť napríklad vstupom z formuláru
if (re.match('^[1-9]\d{2}$',cislo)):
  print "OK"
else:
  print "Chyba! Toto nie je trojciferné číslo!"

Porovnávacie príklady

Podobná funkcia, ktorá ale prehľadáva celý reťazec je re.search().

Obrovským prínosom je používanie skupín. Skupiny v regulárnych výrazoch vyznačíme párom zátvoriek. Nasledujúci regulárny výraz nám vyextrahuje užívateľské meno a doménu z emailovej adresy.

>>> r = re.match('([a-zA-Z0-9_.]+)@([a-zA-Z0-9_.]+)', 'lamp@fornax.sk')
>>> r.group(1) # vypíše reťazec 'lamp' pred zavináčom
'lamp'

>>> r.group(2) # vypíše reťazec 'fornax.sk' za zavináčom
'fornax.sk'

Skupina s číslom 0 je celý reťazec, ktorý zodpovedá regulárnemu výrazu. Ak je index skupiny mimo platný rozsah, dôjde k výnimke IndexError. Python umožňuje jednotlivé skupiny pomenovať pomocou syntaxe: (?P<name>...).

>>> r = re.match('(?P<user>[a-zA-Z0-9_.]+)@(?P<host>[a-zA-Z0-9_.]+)', 'lamp@fornax.sk')
>>> r.group('user') # vypíše reťazec 'lamp'
'lamp'

>>> r.group('host') # vypíše reťazec 'fornax.sk'
'fornax.sk'

Spolu s indexovaním skupín pomocou reťazcov môžeme stále používať aj indexovanie celým číslom, takže r.group(1) je to isté ako r.group('user').

Funkcia re.search() sa neobmedzuje len na začiatok reťazca, ale prehľadáva celý reťazec. Nasledujúci zápis nám v reťazci nájde a vypíše emailovú adresu.

>>> r = re.search(r'([\w.]+@[\w.]+)', 'Adresa lamp@fornax.sk ...')
>>> r.group(1)
'lamp@fornax.sk' # vypíše nájdený reťazec 'lamp@fornax.sk' v reťazci 'Adresa lamp@fornax.sk ...'

Ale funkcia re.search() nám vráti iba prvý výskyt hľadaného výrazu. Na zistenie všetkých výskytov daného regulárneho výrazu môžeme použiť funkciu re.findall().

>>> re.findall(r'[\w.]+@[\w.]+', 'Adresy: honza@py.cz, redakce@root.cz')
'honza@py.cz', 'redakce@root.cz' # výpis emailových adries

Funkcia re.sub(regex, náhrada, subjekt) vykoná hľadanie a výmenu v reťazci subjekt, zamení všetky zhody reťazca regex v reťazci subjekt za reťazec náhrada.

string = "Reťazec má štyri slová."
print string // vypíše pôvodný reťazec
string = re.sub('štyri', '4', string)
print string // vypíše upravený reťazec: "Reťazec má 4 slová."

Porovnávacie príklady

Príznaky regulárnych výrazov

Funkcie re.match() a re.search() možu mať ešte jeden nepovinný argumet flags, ktorý je bitovým súčinom príznakov. Príznaky sú definované ako mená v modulu re:

I, IGNORECASE pri hľadaní sa nerozlišuje veľkosť písmen
L, LOCALE množiny \w, \W, \b a \B budú zodpovedať aktuálnemu locale
M, MULTILINE ovplyvňuje výrazy ^ a $, tie zodpovedajú začiatku, resp. koncu reťazca, s príznakom MULTILINE zodpovedajú aj začiatku aj koncu riadku v reťazci
U, UNICODE množiny \w, \W, \b a \B budú závisieť na tabuľke znakov Unicode
X, VERBOSE umožňuje písať vzhľadovo lepšie vyzerajúce regulárne výrazy