Przejdź do głównej treści
eLearner.app
Moduł 8 · Lekcja 4 z 432/36 w kursie~12 min
Lekcje modułu (4/4)

Moduł re: regex w Pythonie

Moduł re odpowiada za obsługę wyrażeń regularnych w Pythonie. Jeśli ukończyłeś już kurs Regex na tej stronie, cała składnia wyda Ci się znajoma; w tej lekcji przyjrzymy się interfejsom API.

Surowy ciąg znaków (raw string): r"..."

Wyrażenia regularne używają wielu ukośników backslash (\d, \s, \b). Zawsze zapisuj je jako surowe ciągi znaków (raw strings), aby uniknąć konieczności podwajania ukośników:

Python
import re
# raw: \d is a single token
pattern = r"\d+"
# NOT raw: you would have to write "\\d+" otherwise Python interprets \d as "d"

re.search: znajdowanie pierwszego dopasowania

Python
import re
m = re.search(r"\d+", "ho 42 mele e 17 pere")
m.group()    # '42'
m.start()    # 3
m.end()      # 5

Zwraca obiekt Match, jeśli dopasowanie zostało znalezione, w przeciwnym razie None. Idiomatyczny schemat:

Python
if m := re.search(r"\d+", testo):
    print(m.group())

re.match: dopasowanie tylko na początku ciągu znaków

Python
re.match(r"\d+", "42 anni")     # match!
re.match(r"\d+", "ho 42 anni")  # None (doesn't start with a digit)

Do wyszukiwania w dowolnym miejscu ciągu używaj re.search.

re.findall: znajdowanie wszystkich dopasowań

Python
re.findall(r"\d+", "ho 42 mele, 17 pere, 3 banane")
# ['42', '17', '3']

Jeśli wzorzec zawiera grupy przechwytujące, funkcja findall zwraca te grupy, a nie całe dopasowanie:

Python
re.findall(r"(\w+)@(\w+)", "ada@x bob@y")
# [('ada', 'x'), ('bob', 'y')]

re.sub: zastępowanie (podstawianie)

Python
re.sub(r"\d+", "###", "ho 42 mele e 17 pere")
# 'ho ### mele e ### pere'

Działa również z funkcją zamieniającą (która przyjmuje obiekt Match):

Python
re.sub(r"\d+", lambda m: str(int(m.group()) * 2), "ho 42 mele")
# 'ho 84 mele'

Grupy nazwane

Python
m = re.search(r"(?P<anno>\d{4})-(?P<mese>\d{2})-(?P<giorno>\d{2})", "2025-01-15")
m.group("anno")    # '2025'
m.groupdict()      # {'anno': '2025', 'mese': '01', 'giorno': '15'}

Przydatne flagi

Python
re.search(r"ciao", "CIAO", re.IGNORECASE)       # case-insensitive
re.findall(r"^.+$", testo, re.MULTILINE)        # ^/$ match every line
re.search(r"a.b", "a\nb", re.DOTALL)            # . matches newline too

re.finditer dla oszczędności pamięci

Jeśli musisz przetworzyć dopasowania w ogromnym bloku tekstu, re.findall alokuje w pamięci listę zawierającą wszystkie wyodrębnione ciągi. W takich przypadkach zaleca się używanie re.finditer(), które zwraca leniwy generator (lazy iterator) obiektów Match, zużywając minimalną ilość pamięci.

Spróbuj sam

Ćwiczenie#python.m8.l4.e1
Próby: 0Ładowanie...

Dla podanego ciągu `text = 'ordine #123, totale €45.50, ricevuta #456'`, wyodrębnij WSZYSTKIE numery zamówień (cyfry po znaku #) do listy `orders` zawierającej ciągi znaków. Oceń `orders`.

Ładowanie edytora...
Pokaż wskazówkę

re.findall(r"#(\d+)", text) — grupa przechwytująca tylko dla cyfr.

Rozwiązanie dostępne po 3 próbach

Ćwiczenie powtórzeniowe

Ćwiczenie#python.m8.l4.e2
Próby: 0Ładowanie...

Dla ciągu `s = 'tel: 06-12345678 e tel: 02-9876'`, zastąp wszystkie numery telefonów (w formacie \d+-\d+) ciągiem 'XXX' i przypisz wynik do zmiennej `masked`. Oceń `masked`.

Ładowanie edytora...
Pokaż wskazówkę

re.sub(r"\d+-\d+", "XXX", s)

Rozwiązanie dostępne po 3 próbach

Dodatkowe wyzwanie

Ćwiczenie#python.m8.l4.e3
Próby: 0Ładowanie...

Zaimportuj moduł `re`. Wyodrębnij wszystkie liczby składające się z jednej lub więcej cyfr z ciągu `log_line = "Error 404 in 15ms"`. Zapisz tę listę w zmiennej `numbers` i ją oceń.

Ładowanie edytora...
Pokaż wskazówkę

Użyj re.findall(r'\d+', log_line), aby wyodrębnić wszystkie liczby jako listę ciągów znaków.

Rozwiązanie dostępne po 3 próbach