Kódím.cz
2

Regulární výrazy

Ovládneme regulární výrazy, které nám umožní dělat kouzla při dolování dat z textů.

Regulární výrazy v Pythonu

V Pythonu máme řadu funkcí, které můžeme použít pro práci s regulárními výrazy. Projdeme si ty základní. Funkce jsou v modulu re, který je součástí Pythonu a můžeš ho importovat pomocí příkazu import re na začátku programu.

Ověření formátu

Často potřebujeme ověřit, jestli máme zadaná data ve správném formátu. Např. telefonní čísla, rodná čísla, ISBN u knih, poštovní směrovací čísla, e-maily nebo čísla bankovního účtu mají jasně definovaný formát.

Zkusme si nejprve zadat rodné číslo. Víme, že rodné číslo se skládá ze 6 číslic, které kódují datum narození, a tří nebo čtyř číslic, které identifikují konkrétního člověka. Regulární výraz, který by číslo ověřil, je \d{9,10}.

Regulární výraz můžeme vytvořit pomocí funkce compile() z modulu re. Před řetězec s regulárními výrazy píšeme r, abychom Pythonu dali vědět, co je daný řetězec zač.

import re

regularni_vyraz = re.compile(r"\d{9,10}")

rezetec = "9511121234"
print(regularni_vyraz.match(rezetec))
rezetec = "ahoj"
print(regularni_vyraz.match(rezetec))

Pokud funkce match došla k závěru, že se řetězec shoduje s regulárním výrazem, vrátí objekt Match. S ním později budeme pracovat. Pokud by však funkce došla k závěru, že se řetězce s regulárním výrazem neshoduje, vrátí hodnotu označovanou jako None, tj. prázdnou hodnotu.

Otázka: Často je rodné číslo zapisováno ve formátu s podtržítkem, které odděluje datum narození od zbytku. Jak upravíme regulární výraz, aby akceptoval oba formáty, tj. formát s podtržítkem i bez podtržítka?

Přísnější ověření formátu

Pokud chceš ověřit, jestli řetězec odpovídá zadanému výrazu a není tam nic navíc, můžeš použít funkci fullmatch, která funguje stejně jako funkce match().

import re

regularni_vyraz = re.compile(r"\d{9,10}")

rezetec = "9511121234"
print(regularni_vyraz.match(rezetec))
rezetec = "9511121234$ je moje rodné číslo"
print(regularni_vyraz.fullmatch(rezetec))

Zapojení podmínky

Pojďme nyní zapojit do akce podmínku. Můžeme třeba uživateli vypsat, jestli jím zadaná hodnota je správná. Výsledek volání funkce match() můžeme vložit přímo do podmínky, protože podmínka, které nevložíme operátor na porovnávání (např. ==) funguje takto:

  • Pokud podmínce vložíme nějaký smysluplný výraz, vyhodnotí ho jako pravda.
  • Pokud podmínce vložíme prázdnou hodnotu None, vyhodnotí ji jako nepravda.
import re

regularni_vyraz = re.compile(r"\d{9,10}")
vstup = input("Zadej rodné číslo: ")
hledani = regularni_vyraz.fullmatch(vstup)
if hledani:
    print("Rodné číslo je v pořádku!")
else:
    print("Nesprávné rodné číslo!")

E-maily

Pokud např. dostaneme e-mail info@czechitas.cz, víme, že je v pořádku. E-mail info@czechitascz by ale v pořádku nebyl, protože "koncovka" "cz" (v řeči počítačů doména prvního řádu) musí být oddělena tečkou.

import re

regularni_vyraz = re.compile(r"\w+@\w+\.cz")
email = input("Zadej e-mail: ")
hledani = regularni_vyraz.fullmatch(email)
if hledani:
    print("E-mail je v pořádku!")
else:
    print("Nesprávný e-mail!")

Vyhledávání

Kromě ověřování správného formátu můžeme použít regulární výrazy i k vyhledávání. Například funkce findall vrátí ze zadaného řetězce všechny podřetězce, které odpovídají danému regulárnímu výrazu, jako seznam.

Následující program například z deníku lékaře vyhledá rodná čísla všech pacientů, které lékař zmínil.

import re

zapis = """
Zápisy o provedených vyšetřeních:
Pacient 6407156800 trpěl bolestí zad a byl poslán na vyšetření. 
Pacientka 8655057477 přišla na kontrolu po zranění kotníku.
Do ordinace telefonovala pacientka 7752126712, které byl elektronicky vydán recept na Paralen. 
"""

regularni_vyraz = re.compile(r"\d{9,10}")
vysledky = regularni_vyraz.findall(zapis)
for vysledek in vysledky:
    print(vysledek)

Nahrazování

Uvažujme, že máme nějakém textu provést anonymizaci, tj. vymazat všechny osobní údaje. K tomu můžeme využít funkci sub(), která nahradí všechny podřetězce, které odpovídají regulárnímu výrazu, námi zadanou hodnotou.

import re

zapis = """
Zápisy o provedených vyšetřeních:
Pacient 6407156800 trpěl bolestí zad a byl poslán na vyšetření. 
Pacientka 8655057477 přišla na kontrolu po zranění kotníku.
Do ordinace telefonovala pacientka 7752126712, které byl elektronicky vydán recept na Paralen. 
"""

regularni_vyraz = re.compile(r"\d{9,10}")
anonymniZapis = regularni_vyraz.sub("X" * 9, zapis)
print(anonymniZapis)

Cvičení: Regulární výrazy v Pythonu