13. Python – operacje na ciągach i wyrażenia regularne


String (ciąg znaków, łańcuch znaków) to jeden z najważniejszych typów danych w Pythonie. String to sekwencja znaków – liter, cyfr, spacji, symboli.

  • Stringi są niemutowalne (nie można zmienić, tylko utworzyć nowy)
  • Można używać pojedynczych '...' lub podwójnych "..." cudzysłowów
  • Obsługują Unicode (polskie znaki działają bez problemu)

Tworzenie stringów

Podstawowe sposoby

# Pojedyncze cudzysłowy
tekst1 = 'Hello World'

# Podwójne cudzysłowy
tekst2 = "Python Programming"

# Wieloliniowe - potrójne cudzysłowy
tekst3 = """To jest
tekst wieloliniowy
w trzech liniach"""

tekst4 = '''Można też
użyć pojedynczych
potrójnych'''

print(tekst3)

Kiedy używać pojedynczych, a kiedy podwójnych?

# Gdy w tekście jest apostrof
tekst1 = "It's a beautiful day"

# Gdy w tekście są cudzysłowy
tekst2 = 'Powiedział "Hello"'

# Escape - znak ucieczki
tekst3 = 'It\'s a beautiful day'  # Też działa
tekst4 = "Powiedział \"Hello\""   # Też działa

Konwencja: Wybierz jeden styl i trzymaj się go konsekwentnie w projekcie.

Pusty string

pusty1 = ""
pusty2 = str()

print(len(pusty1))  # 0
print(len(pusty2))  # 0

Znaki specjalne (escape sequences)

# \n - nowa linia
print("Linia 1\nLinia 2")

# \t - tabulacja
print("Kolumna1\tKolumna2")

# \\ - backslash
print("Ścieżka: C:\\Users\\Jan")

# \' i \" - cudzysłowy
print('He said: "It\'s great!"')

# Raw string - ignoruje escape
print(r"C:\nowy\test")  # Wypisze dosłownie \n

Wynik:

Linia 1
Linia 2
Kolumna1	Kolumna2
Ścieżka: C:\Users\Jan
He said: "It's great!"
C:\nowy\test

Konkatenacja (łączenie stringów)

Operator +

imie = "Jan"
nazwisko = "Kowalski"

pelen_imie = imie + " " + nazwisko
print(pelen_imie)  # Jan Kowalski

# Można łączyć wiele stringów
adres = "ul. " + "Słoneczna" + " " + "5"
print(adres)  # ul. Słoneczna 5

Operator * (powtarzanie)

# Powtarzanie stringa
print("=" * 50)  # ==================================================
print("Ha" * 3)  # HaHaHa

# Praktyczne zastosowanie
separator = "-" * 30
print(separator)

Łączenie z innymi typami

# ŹLE - nie można łączyć string + int
wiek = 25
# print("Mam " + wiek + " lat")  # TypeError!

# DOBRZE - konwersja na string
print("Mam " + str(wiek) + " lat")

# LEPIEJ - f-stringi (poniżej)
print(f"Mam {wiek} lat")

Indeksowanie i wycinanie (slicing)

Stringi są sekwencjami – można uzyskać dostęp do pojedynczych znaków.

Indeksowanie

tekst = "Python"

# Indeksy od 0
print(tekst[0])  # P
print(tekst[1])  # y
print(tekst[5])  # n

# Ujemne indeksy (od końca)
print(tekst[-1])  # n (ostatni)
print(tekst[-2])  # o (przedostatni)

# IndexError jeśli poza zakresem
# print(tekst[10])  # IndexError!

Schemat indeksów:

 P  y  t  h  o  n
 0  1  2  3  4  5   (dodatnie)
-6 -5 -4 -3 -2 -1   (ujemne)

Slicing (wycinki)

Składnia: string[start:stop:step]

  • Składnia: string[start:stop:step]
tekst = "Python Programming"

# Podstawowe wycinki
print(tekst[0:6])    # Python
print(tekst[7:18])   # Programming

# Pominięcie start (od początku)
print(tekst[:6])     # Python

# Pominięcie stop (do końca)
print(tekst[7:])     # Programming

# Co drugi znak
print(tekst[::2])    # Pto rgamn

# Odwrócenie stringa
print(tekst[::-1])   # gnimmargorP nohtyP

Przykłady praktyczne

email = "jan.kowalski@example.com"

# Wyciągnij nazwę użytkownika (przed @)
at_index = email.index('@')
username = email[:at_index]
print(username)  # jan.kowalski

# Wyciągnij domenę (po @)
domain = email[at_index+1:]
print(domain)  # example.com

# Ostatnie 3 znaki
print(email[-3:])  # com

Długość stringa – len()

tekst = "Python"
print(len(tekst))  # 6

# Pusty string
print(len(""))  # 0

# Ze spacjami
zdanie = "Hello World"
print(len(zdanie))  # 11 (spacja też się liczy)

Metody stringów

Python ma wbudowanych ponad 40 metod do pracy ze stringami. Oto najważniejsze:

upper() i lower() – zmiana wielkości liter

tekst = "Python Programming"

# Wszystkie wielkie
print(tekst.upper())  # PYTHON PROGRAMMING

# Wszystkie małe
print(tekst.lower())  # python programming

# Praktyczne zastosowanie - porównywanie bez względu na wielkość
haslo = "Python123"
if haslo.lower() == "python123":
    print("Hasło poprawne")

capitalize() – pierwsza litera wielka

tekst = "python programming"
print(tekst.capitalize())  # Python programming

# Tylko pierwsza litera całego stringa!
zdanie = "ala ma kota"
print(zdanie.capitalize())  # Ala ma kota

title() – każde słowo z wielkiej litery

tekst = "python programming language"
print(tekst.title())  # Python Programming Language

# Przydatne dla imion i nazwisk
imie = "jan kowalski"
print(imie.title())  # Jan Kowalski

strip(), lstrip(), rstrip() – usuwanie białych znaków

tekst = "   Python   "

# Usuń spacje z obu stron
print(tekst.strip())   # "Python"

# Usuń spacje z lewej
print(tekst.lstrip())  # "Python   "

# Usuń spacje z prawej
print(tekst.rstrip())  # "   Python"

# Praktyczne - dane z inputu
nazwa = input("Podaj imię: ").strip()

Usuwanie konkretnych znaków

tekst = "###Python###"

# Usuń # z obu stron
print(tekst.strip('#'))  # Python

# Usuń kilka znaków
tekst2 = "...Python!!!"
print(tekst2.strip('.!'))  # Python

split() – dzielenie na listę

zdanie = "Python jest super"

# Dziel po spacjach (domyślnie)
slowa = zdanie.split()
print(slowa)  # ['Python', 'jest', 'super']

# Dziel po konkretnym separatorze
data = "2024-01-15"
elementy = data.split('-')
print(elementy)  # ['2024', '01', '15']

# CSV - dziel po przecinku
dane = "Jan,Kowalski,25,Warszawa"
lista = dane.split(',')
print(lista)  # ['Jan', 'Kowalski', '25', 'Warszawa']

join() – łączenie listy w string

# Lista słów
slowa = ['Python', 'jest', 'super']

# Połącz spacjami
zdanie = ' '.join(slowa)
print(zdanie)  # Python jest super

# Połącz innym separatorem
zdanie2 = '-'.join(slowa)
print(zdanie2)  # Python-jest-super

# Bez separatora
slowo = ''.join(['P', 'y', 't', 'h', 'o', 'n'])
print(slowo)  # Python

replace() – zamiana tekstu

tekst = "Python is awesome"

# Zamień "awesome" na "great"
nowy = tekst.replace("awesome", "great")
print(nowy)  # Python is great

# Oryginalny string NIE zmieniony (niemutowalność)
print(tekst)  # Python is awesome

# Zamień wszystkie wystąpienia
zdanie = "ala ma kota, kot ma ale"
nowe = zdanie.replace("a", "@")
print(nowe)  # @l@ m@ kot@, kot m@ @le

# Ogranicz liczbę zamian
nowe2 = zdanie.replace("a", "@", 2)  # Tylko 2 pierwsze
print(nowe2)  # @l@ ma kota, kot ma ale

find() i index() – wyszukiwanie

tekst = "Python Programming"

# find() - zwraca indeks lub -1
print(tekst.find('P'))        # 0
print(tekst.find('Programming'))  # 7
print(tekst.find('Java'))     # -1 (nie znaleziono)

# index() - zwraca indeks lub błąd
print(tekst.index('P'))       # 0
# print(tekst.index('Java'))  # ValueError!

# Praktyczne - sprawdzanie czy zawiera
if tekst.find('Python') != -1:
    print("Zawiera Python")

count() – zliczanie wystąpień

tekst = "ala ma kota, kot ma ale"

print(tekst.count('a'))     # 6
print(tekst.count('ma'))    # 2
print(tekst.count('kot'))   # 2

# Case-sensitive
print(tekst.count('A'))     # 0

startswith() i endswith() – sprawdzanie początku/końca

plik = "dokument.pdf"

# Czy zaczyna się od...
print(plik.startswith('dok'))     # True
print(plik.startswith('test'))    # False

# Czy kończy się na...
print(plik.endswith('.pdf'))      # True
print(plik.endswith('.txt'))      # False

# Praktyczne - walidacja plików
if plik.endswith(('.pdf', '.doc', '.docx')):
    print("To dokument")

isdigit(), isalpha(), isalnum() – sprawdzanie typu

# isdigit() - czy tylko cyfry
print("123".isdigit())       # True
print("12a".isdigit())       # False

# isalpha() - czy tylko litery
print("Python".isalpha())    # True
print("Python3".isalpha())   # False

# isalnum() - czy litery lub cyfry
print("Python3".isalnum())   # True
print("Python 3".isalnum())  # False (spacja)

# islower() - czy małe litery
print("python".islower())    # True

# isupper() - czy wielkie litery
print("PYTHON".isupper())    # True

# isspace() - czy białe znaki
print("   ".isspace())       # True

Przykład – walidacja inputu

def pobierz_wiek():
    """Pobiera wiek z walidacją"""
    while True:
        wiek = input("Podaj wiek: ").strip()
        
        if wiek.isdigit():
            return int(wiek)
        else:
            print("Błąd: wpisz liczbę!")

wiek = pobierz_wiek()
print(f"Twój wiek: {wiek}")

Formatowanie stringów

Metoda 1: Konkatenacja

imie = "Jan"
wiek = 25

# ŹLE - nieczytelne
wiadomosc = "Cześć, " + imie + "! Masz " + str(wiek) + " lat."
print(wiadomosc)

Metoda 2: format()

imie = "Jan"
wiek = 25

# Podstawienie po kolei
wiadomosc = "Cześć, {}! Masz {} lat.".format(imie, wiek)
print(wiadomosc)

# Numerowane
wiadomosc = "Cześć, {0}! {0}, masz {1} lat.".format(imie, wiek)
print(wiadomosc)  # Cześć, Jan! Jan, masz 25 lat.

# Nazwane
wiadomosc = "Cześć, {name}! Masz {age} lat.".format(name=imie, age=wiek)
print(wiadomosc)

Metoda 3: f-stringi (NAJLEPSZE – Python 3.6+)

imie = "Jan"
wiek = 25
wzrost = 1.75

# f-string - najwygodniejsze
wiadomosc = f"Cześć, {imie}! Masz {wiek} lat i {wzrost}m wzrostu."
print(wiadomosc)

# Można wykonywać operacje
print(f"Za rok będziesz miał {wiek + 1} lat")

# Formatowanie liczb
cena = 19.99
print(f"Cena: {cena:.2f} zł")  # Cena: 19.99 zł

liczba = 1234.5678
print(f"{liczba:.2f}")   # 1234.57 (2 miejsca po przecinku)
print(f"{liczba:10.2f}") # "   1234.57" (wyrównanie do 10)

Formatowanie f-stringów

# Wyrównanie
tekst = "Python"
print(f"|{tekst:<10}|")  # |Python    | (do lewej)
print(f"|{tekst:>10}|")  # |    Python| (do prawej)
print(f"|{tekst:^10}|")  # |  Python  | (wyśrodkowane)

# Liczby
liczba = 42
print(f"{liczba:05d}")   # 00042 (dopełnienie zerami)
print(f"{liczba:b}")     # 101010 (binarne)
print(f"{liczba:x}")     # 2a (hex)

# Procenty
udzial = 0.75
print(f"{udzial:.1%}")   # 75.0%

# Tysiące
wielka = 1234567
print(f"{wielka:,}")     # 1,234,567

Sprawdzanie zawartości

Operator in

tekst = "Python Programming"

# Czy zawiera
print("Python" in tekst)      # True
print("Java" in tekst)        # False

# Czy NIE zawiera
print("Ruby" not in tekst)    # True

# Praktyczne - walidacja
email = "jan@example.com"
if '@' in email and '.' in email:
    print("Email wygląda poprawnie")

Iteracja po stringu

tekst = "Python"

# Każdy znak osobno
for znak in tekst:
    print(znak)
# P
# y
# t
# h
# o
# n

# Z indeksem
for i, znak in enumerate(tekst):
    print(f"Indeks {i}: {znak}")
# Indeks 0: P
# Indeks 1: y
# ...

Niemutowalność stringów

WAŻNE: Stringi w Pythonie są niemutowalne – nie można ich zmienić, tylko utworzyć nowy.

tekst = "Python"

# ŹLE - nie można zmienić
# tekst[0] = 'J'  # TypeError!

# DOBRZE - tworzenie nowego stringa
nowy_tekst = 'J' + tekst[1:]
print(nowy_tekst)  # Jython

# Metody tworzą nowe stringi
tekst = "python"
wielkie = tekst.upper()  # Nowy string
print(tekst)    # python (oryginalny bez zmian)
print(wielkie)  # PYTHON (nowy)

Zaawansowane operacje

Usuwanie znaków

tekst = "Python Programming!"

# Usuń wykrzyknik
nowy = tekst.replace('!', '')
print(nowy)  # Python Programming

# Usuń wszystkie znaki interpunkcyjne
import string
nowy = tekst.translate(str.maketrans('', '', string.punctuation))
print(nowy)  # Python Programming

Zamiana wielkości liter wybranych znaków

tekst = "Python Programming"

# swapcase() - zamień małe na wielkie i odwrotnie
print(tekst.swapcase())  # pYTHON pROGRAMMING

Wyrównywanie tekstu

tekst = "Python"

# center() - wyśrodkowanie
print(tekst.center(20))       # "       Python       "
print(tekst.center(20, '*'))  # "*******Python*******"

# ljust() - wyrównanie do lewej
print(tekst.ljust(20, '.'))   # "Python.............."

# rjust() - wyrównanie do prawej
print(tekst.rjust(20, '.'))   # "..............Python"

# zfill() - dopełnienie zerami
numer = "42"
print(numer.zfill(5))         # "00042"

Sprawdzanie identyfikatorów

# isidentifier() - czy może być nazwą zmiennej
print("zmienna".isidentifier())    # True
print("2zmienna".isidentifier())   # False
print("_private".isidentifier())   # True
print("for".isidentifier())        # True (ale keyword!)

# iskeyword() z modułu keyword
import keyword
print(keyword.iskeyword("for"))    # True
print(keyword.iskeyword("zmienna")) # False

Kodowanie znaków

ord() i chr() – konwersja znak ↔ kod ASCII

# chr() - kod → znak
print(chr(65))   # A
print(chr(97))   # a
print(chr(48))   # 0

# ord() - znak → kod
print(ord('A'))  # 65
print(ord('a'))  # 97
print(ord('0'))  # 48

# Polskie znaki (Unicode)
print(ord('ą'))  # 261
print(chr(261))  # ą

encode() i decode() – kodowanie

tekst = "Zażółć gęślą jaźń"

# String → bajty (kodowanie)
bajty = tekst.encode('utf-8')
print(bajty)  # b'Za\xc5\xbc\xc3\xb3\xc5\x82\xc4\x87...'
print(type(bajty))  # <class 'bytes'>

# Bajty → string (dekodowanie)
z_powrotem = bajty.decode('utf-8')
print(z_powrotem)  # Zażółć gęślą jaźń

Parsowanie stringów

Wyciąganie liczb z tekstu

import re

tekst = "Mam 25 lat i 180cm wzrostu"

# Znajdź wszystkie liczby
liczby = re.findall(r'\d+', tekst)
print(liczby)  # ['25', '180']

# Konwersja na int
liczby_int = [int(x) for x in liczby]
print(liczby_int)  # [25, 180]

Parsowanie daty

data = "2024-01-15"
rok, miesiac, dzien = data.split('-')

print(f"Rok: {rok}")
print(f"Miesiąc: {miesiac}")
print(f"Dzień: {dzien}")

Parsowanie CSV

wiersz = "Jan,Kowalski,25,Warszawa"
dane = wiersz.split(',')

imie, nazwisko, wiek, miasto = dane
print(f"{imie} {nazwisko}, {wiek} lat, {miasto}")

Przykłady praktyczne

Przykład 1: Walidacja hasła

def waliduj_haslo(haslo):
    """
    Sprawdza czy hasło jest silne:
    - minimum 8 znaków
    - zawiera wielką literę
    - zawiera małą literę
    - zawiera cyfrę
    """
    if len(haslo) < 8:
        return False, "Za krótkie (min 8 znaków)"
    
    if not any(c.isupper() for c in haslo):
        return False, "Brak wielkiej litery"
    
    if not any(c.islower() for c in haslo):
        return False, "Brak małej litery"
    
    if not any(c.isdigit() for c in haslo):
        return False, "Brak cyfry"
    
    return True, "Hasło silne"

# Test
haslo = "Python123"
ok, komunikat = waliduj_haslo(haslo)
print(f"{haslo}: {komunikat}")

Przykład 2: Cenzurowanie wulgaryzmów

def cenzuruj(tekst, slowa_zakazane):
    """Zamienia zakazane słowa na ***"""
    tekst_lower = tekst.lower()
    
    for slowo in slowa_zakazane:
        if slowo.lower() in tekst_lower:
            tekst = tekst.replace(slowo, '*' * len(slowo))
    
    return tekst

tekst = "To jest test brzydkiego słowa"
zakazane = ["brzydki", "test"]
print(cenzuruj(tekst, zakazane))
# To jest **** ********* słowa

Przykład 3: Skrócenie tekstu

def skroc_tekst(tekst, max_dlugosc=50):
    """Skraca tekst do max długości dodając ..."""
    if len(tekst) <= max_dlugosc:
        return tekst
    
    return tekst[:max_dlugosc-3] + "..."

dlugi_tekst = "To jest bardzo długi tekst, który musi być skrócony do rozsądnej długości"
print(skroc_tekst(dlugi_tekst, 30))
# To jest bardzo długi tekst...

Przykład 4: Usuwanie duplikatów słów

def usun_duplikaty_slow(zdanie):
    """Usuwa powtarzające się słowa zachowując kolejność"""
    slowa = zdanie.split()
    unikalne = []
    
    for slowo in slowa:
        if slowo not in unikalne:
            unikalne.append(slowo)
    
    return ' '.join(unikalne)

zdanie = "ala ma ma kota kot ma ale"
print(usun_duplikaty_slow(zdanie))
# ala ma kota kot ale

Przykład 5: Formatowanie numeru telefonu

def formatuj_telefon(numer):
    """Formatuje numer telefonu na XXX-XXX-XXX"""
    # Usuń wszystkie znaki nie będące cyframi
    cyfry = ''.join(c for c in numer if c.isdigit())
    
    if len(cyfry) != 9:
        return "Niepoprawny numer"
    
    return f"{cyfry[:3]}-{cyfry[3:6]}-{cyfry[6:]}"

print(formatuj_telefon("123456789"))     # 123-456-789
print(formatuj_telefon("123 456 789"))   # 123-456-789
print(formatuj_telefon("+48123456789"))  # 123-456-789

Przykład 6: Zliczanie słów

def statystyki_tekstu(tekst):
    """Zwraca statystyki tekstu"""
    slowa = tekst.split()
    
    return {
        'znaki': len(tekst),
        'znaki_bez_spacji': len(tekst.replace(' ', '')),
        'slowa': len(slowa),
        'zdania': tekst.count('.') + tekst.count('!') + tekst.count('?'),
        'srednia_dlugosc_slowa': sum(len(s) for s in slowa) / len(slowa) if slowa else 0
    }

tekst = "Python to świetny język. Jest prosty i potężny!"
stats = statystyki_tekstu(tekst)

for klucz, wartosc in stats.items():
    print(f"{klucz}: {wartosc}")

Przykład 7: Palindrom

def czy_palindrom(tekst):
    """Sprawdza czy tekst jest palindromem"""
    # Usuń spacje i zamień na małe litery
    oczyszczony = tekst.replace(' ', '').lower()
    
    # Porównaj z odwróconym
    return oczyszczony == oczyszczony[::-1]

print(czy_palindrom("kajak"))           # True
print(czy_palindrom("Kobyła ma mały bok"))  # True
print(czy_palindrom("python"))          # False

Przykład 8: Generator inicjałów

def inicjaly(pelne_imie):
    """Generuje inicjały z pełnego imienia"""
    slowa = pelne_imie.split()
    return '.'.join(s[0].upper() for s in slowa) + '.'

print(inicjaly("Jan Kowalski"))          # J.K.
print(inicjaly("Adam Bernard Mickiewicz"))  # A.B.M.

Moduł string

Python ma wbudowany moduł string z użytecznymi stałymi.

import string

# Wszystkie litery
print(string.ascii_letters)
# abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ

print(string.ascii_lowercase)
# abcdefghijklmnopqrstuvwxyz

print(string.ascii_uppercase)
# ABCDEFGHIJKLMNOPQRSTUVWXYZ

# Cyfry
print(string.digits)
# 0123456789

# Znaki interpunkcyjne
print(string.punctuation)
# !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

# Białe znaki
print(string.whitespace)
# ' \t\n\r\x0b\x0c'

Praktyczne zastosowanie:

import string
import random

def generuj_haslo(dlugosc=12):
    """Generuje losowe hasło"""
    znaki = string.ascii_letters + string.digits + string.punctuation
    return ''.join(random.choice(znaki) for _ in range(dlugosc))

print(generuj_haslo())  # aB3$dK9!mQ1@
print(generuj_haslo(20))  # Dłuższe hasło

Wyrażenia regularne (regex) – podstawy

Dla zaawansowanego przetwarzania tekstów używa się modułu re.

Wyrażenia regularne (Regular Expressions, regex) to wzorce używane do wyszukiwania i manipulowania tekstem. Pozwalają na zaawansowane operacje, których nie da się łatwo wykonać zwykłymi metodami stringów tj.

  • Znajdowanie skomplikowanych wzorców (np. email, telefon, URL)
  • Walidacja danych
  • Ekstrakcja informacji z tekstu
  • Zamiana tekstu według wzorca

Moduł re – podstawy

Import i podstawowe funkcje

import re

# Główne funkcje:
# re.search()  - znajdź pierwsze dopasowanie
# re.findall() - znajdź wszystkie dopasowania
# re.match()   - sprawdź czy zaczyna się od wzorca
# re.sub()     - zamień dopasowania
# re.split()   - podziel według wzorca

Podstawowe wzorce

Dopasowanie dosłowne

import re

tekst = "Python is awesome"

# Znajdź słowo "Python"
wynik = re.search('Python', tekst)
if wynik:
    print("Znaleziono!")  # Znaleziono!
    print(wynik.group())  # Python

Metaznaki specjalne

ZnakZnaczeniePrzykład
.Dowolny znak (oprócz \n)a.c → „abc”, „a5c”
^Początek stringa^Hello → „Hello world” ✓
$Koniec stringaend$ → „The end” ✓
*0 lub więcejab*c → „ac”, „abc”, „abbc”
+1 lub więcejab+c → „abc”, „abbc” (nie „ac”)
?0 lub 1ab?c → „ac”, „abc”
\Znak ucieczki\. → dosłowna kropka

Klasy znaków

Predefiniowane klasy

import re

# \d - cyfra (digit) [0-9]
print(re.findall(r'\d', 'Python 3.12'))  
# ['3', '1', '2']

# \D - NIE cyfra
print(re.findall(r'\D', 'Python 3.12'))  
# ['P', 'y', 't', 'h', 'o', 'n', ' ', '.']

# \w - znak alfanumeryczny [a-zA-Z0-9_]
print(re.findall(r'\w', 'Hello World!'))  
# ['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd']

# \W - NIE alfanumeryczny
print(re.findall(r'\W', 'Hello World!'))  
# [' ', '!']

# \s - biały znak (spacja, tab, newline)
print(re.findall(r'\s', 'Hello World'))  
# [' ']

# \S - NIE biały znak
print(re.findall(r'\S', 'Hello World'))  
# ['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd']

Ważne: Używaj r-stringów (r'...') aby uniknąć problemów z backslashami!

Własne klasy znaków

import re

# [abc] - jeden z: a, b lub c
print(re.findall(r'[abc]', 'abcdef'))  
# ['a', 'b', 'c']

# [a-z] - zakres małych liter
print(re.findall(r'[a-z]', 'Hello World'))  
# ['e', 'l', 'l', 'o', 'o', 'r', 'l', 'd']

# [A-Z] - zakres wielkich liter
print(re.findall(r'[A-Z]', 'Hello World'))  
# ['H', 'W']

# [0-9] - zakres cyfr (to samo co \d)
print(re.findall(r'[0-9]', 'Python 3.12'))  
# ['3', '1', '2']

# [a-zA-Z] - małe i wielkie litery
print(re.findall(r'[a-zA-Z]', 'Hello 123'))  
# ['H', 'e', 'l', 'l', 'o']

# [^abc] - wszystko OPRÓCZ a, b, c
print(re.findall(r'[^abc]', 'abcdef'))  
# ['d', 'e', 'f']

Kwantyfikatory (ile razy)

import re

tekst = "aa aaa aaaa b bb bbb"

# * - 0 lub więcej
print(re.findall(r'a*', tekst))  
# Znajdzie każde wystąpienie (nawet puste)

# + - 1 lub więcej
print(re.findall(r'a+', tekst))  
# ['aa', 'aaa', 'aaaa']

# ? - 0 lub 1
print(re.findall(r'ab?', 'a ab abb'))  
# ['a', 'ab', 'ab']

# {n} - dokładnie n razy
print(re.findall(r'a{3}', tekst))  
# ['aaa', 'aaa']  (z aaaa znajduje pierwsze 3)

# {n,} - n lub więcej
print(re.findall(r'a{2,}', tekst))  
# ['aa', 'aaa', 'aaaa']

# {n,m} - między n a m
print(re.findall(r'a{2,3}', tekst))  
# ['aa', 'aaa', 'aaa']

Funkcje modułu re

re.search() – znajdź pierwsze dopasowanie

import re

tekst = "Mój numer to 123-456-789"

# Znajdź numer telefonu
wynik = re.search(r'\d{3}-\d{3}-\d{3}', tekst)

if wynik:
    print("Znaleziono:", wynik.group())  
    # Znaleziono: 123-456-789
    print("Pozycja:", wynik.start(), "-", wynik.end())  
    # Pozycja: 13 - 25
else:
    print("Nie znaleziono")

re.findall() – znajdź wszystkie dopasowania

import re

tekst = "Telefony: 123-456-789 i 987-654-321"

# Znajdź wszystkie numery
numery = re.findall(r'\d{3}-\d{3}-\d{3}', tekst)
print(numery)  
# ['123-456-789', '987-654-321']

# Znajdź wszystkie słowa
slowa = re.findall(r'\w+', tekst)
print(slowa)  
# ['Telefony', '123', '456', '789', 'i', '987', '654', '321']

# Znajdź wszystkie liczby
liczby = re.findall(r'\d+', tekst)
print(liczby)  
# ['123', '456', '789', '987', '654', '321']

re.match() – sprawdź początek stringa

import re

# match() sprawdza TYLKO początek!
tekst1 = "Python is great"
tekst2 = "I love Python"

print(re.match(r'Python', tekst1))  # <Match object>
print(re.match(r'Python', tekst2))  # None (Python nie na początku)

# Praktyczne użycie
if re.match(r'https://', 'https://example.com'):
    print("To link HTTPS")

re.sub() – zamiana

import re

tekst = "Mój numer to 123-456-789"

# Zamień numer na ***
nowy = re.sub(r'\d{3}-\d{3}-\d{3}', '***', tekst)
print(nowy)  
# Mój numer to ***

# Usuń wszystkie cyfry
bez_cyfr = re.sub(r'\d', '', tekst)
print(bez_cyfr)  
# Mój numer to --

# Zamień wiele spacji na jedną
tekst2 = "Python    is     great"
normalny = re.sub(r' +', ' ', tekst2)
print(normalny)  
# Python is great

re.split() – podział

import re

# Podziel po wielu separatorach
tekst = "jabłko,gruszka;banan:arbuz"
owoce = re.split(r'[,;:]', tekst)
print(owoce)  
# ['jabłko', 'gruszka', 'banan', 'arbuz']

# Podziel po białych znakach (spacje, taby, newlines)
tekst2 = "Python  is\tgreat\n"
slowa = re.split(r'\s+', tekst2)
print(slowa)  
# ['Python', 'is', 'great', '']

Gotowe wzorce

# Email (prosty)
r'[\w\.-]+@[\w\.-]+\.\w+'

# Telefon (format: 123-456-789)
r'\d{3}-\d{3}-\d{3}'

# URL (http/https)
r'https?://[\w\.-]+'

# Data (DD-MM-YYYY)
r'\d{2}-\d{2}-\d{4}'

# Kod pocztowy (XX-XXX)
r'\d{2}-\d{3}'

# Hashtag
r'#\w+'

# Liczba całkowita
r'-?\d+'

# Liczba zmiennoprzecinkowa
r'-?\d+\.\d+'

Grupy i wyciąganie danych

Grupy w nawiasach ()

import re

tekst = "Jan Kowalski, 25 lat"

# Grupy w nawiasach
wzorzec = r'(\w+) (\w+), (\d+) lat'
wynik = re.search(wzorzec, tekst)

if wynik:
    print("Pełne dopasowanie:", wynik.group(0))  
    # Jan Kowalski, 25 lat
    print("Grupa 1 (imię):", wynik.group(1))     
    # Jan
    print("Grupa 2 (nazwisko):", wynik.group(2)) 
    # Kowalski
    print("Grupa 3 (wiek):", wynik.group(3))     
    # 25
    
    # Wszystkie grupy
    print("Wszystkie:", wynik.groups())          
    # ('Jan', 'Kowalski', '25')

findall() z grupami

import re

tekst = "jan@example.com, anna@test.pl, piotr@gmail.com"

# Wyciągnij nazwy i domeny
wzorzec = r'(\w+)@([\w\.]+)'
wyniki = re.findall(wzorzec, tekst)

for nazwa, domena in wyniki:
    print(f"Użytkownik: {nazwa}, Domena: {domena}")
# Użytkownik: jan, Domena: example.com
# Użytkownik: anna, Domena: test.pl
# Użytkownik: piotr, Domena: gmail.com

Narzędzia online do testowania

Ćwiczenia – Operacje na stringach

Podstawy

  1. Stwórz zmienną z Twoim imieniem i wyświetl ją.
  2. Stwórz zmienne z imieniem i nazwiskiem. Połącz je w pełne imię.
  3. Stwórz string wieloliniowy zawierający Twój adres (3 linie).
  4. Wyświetl string „Python” 10 razy w jednej linii.
  5. Stwórz separator z 50 znaków „=” i wyświetl go.

Indeksowanie i slicing

  1. Pobierz pierwszą literę słowa „Python”.
  2. Pobierz ostatnią literę słowa „Python”.
  3. Pobierz pierwsze 3 litery słowa „Programming”.
  4. Pobierz ostatnie 3 litery słowa „Programming”.
  5. Odwróć słowo „Python” używając slicingu.
  6. Pobierz co drugą literę ze słowa „Python”.
  7. Z adresu email „jan.kowalski@example.com” wyciągnij nazwę użytkownika (przed @).
  8. Z adresu email „jan.kowalski@example.com” wyciągnij domenę (po @).
  9. Ze stringa „2024-01-15” wyciągnij rok, miesiąc i dzień osobno.
  10. Z numeru telefonu „123456789” zrób format „XXX-XXX-XXX” używając slicingu.

len() i podstawowe operacje

  1. Policz długość słowa „Python”.
  2. Pobierz od użytkownika zdanie i wyświetl jego długość.
  3. Sprawdź czy słowo „Python” ma więcej niż 5 liter.
  4. Pobierz hasło od użytkownika i sprawdź czy ma minimum 8 znaków.
  5. Policz ile znaków (wraz ze spacjami) ma zdanie „Python jest super”.

upper(), lower(), capitalize(), title()

  1. Zamień „python” na wielkie litery.
  2. Zamień „PYTHON” na małe litery.
  3. Pobierz imię od użytkownika i zamień pierwszą literę na wielką.
  4. Pobierz zdanie i zamień każde słowo tak aby zaczynało się od wielkiej litery.
  5. Porównaj dwa stringi ignorując wielkość liter.
  6. Stwórz funkcję która sprawdza czy hasło jest poprawne (ignorując wielkość liter).
  7. Zamień „Hello World” tak aby małe litery były wielkie i odwrotnie.
  8. Pobierz od użytkownika imię i nazwisko, sformatuj je title().
  9. Stwórz listę imion i zamień wszystkie na małe litery.
  10. Sprawdź czy string składa się tylko z wielkich liter.

strip(), lstrip(), rstrip()

  1. Usuń spacje z ” Python ” z obu stron.
  2. Usuń spacje tylko z lewej strony ” Python „.
  3. Usuń spacje tylko z prawej strony ” Python „.
  4. Usuń znaki „#” z „###Python###”.
  5. Pobierz dane od użytkownika i usuń niepotrzebne spacje.
  6. Usuń znaki „.” i „!” z początku i końca stringa.
  7. Oczyść listę stringów ze spacji.
  8. Stwórz funkcję która normalizuje input (strip + lower).
  9. Usuń tabulatory i nowe linie z początku i końca tekstu.
  10. Oczyść dane z formularza (strip dla każdego pola).

split() i join()

  1. Podziel zdanie „Python jest super” na listę słów.
  2. Podziel datę „2024-01-15” po myślnikach.
  3. Podziel dane CSV „Jan,Kowalski,25,Warszawa” po przecinkach.
  4. Połącz listę [’Python’, 'jest’, 'super’] w zdanie.
  5. Połącz listę [’2024′, ’01’, ’15’] w datę z myślnikami.
  6. Podziel ścieżkę „C:\Users\Jan\Documents” po backslashach.
  7. Z tekstu z wieloma spacjami zrób listę słów (split bez argumentu).
  8. Połącz listę słów przecinkami.
  9. Podziel tekst po nowych liniach (\n).
  10. Stwórz funkcję która zamienia spacje na podkreślniki.

replace()

  1. Zamień „Python” na „Java” w zdaniu „Python jest super”.
  2. Zamień wszystkie spacje na podkreślniki.
  3. Usuń wszystkie wykrzykniki ze zdania.
  4. Zamień pierwsze 3 wystąpienia „a” na „@”.
  5. Cenzuruj wulgaryzm zastępując go gwiazdkami.
  6. Zamień polskie znaki na łacińskie (ą→a, ę→e).
  7. Usuń wszystkie cyfry z tekstu (zamień na pusty string).
  8. Zamień podwójne spacje na pojedyncze.
  9. Usuń wszystkie samogłoski z tekstu.
  10. Stwórz funkcję zamieniającą „yes” i „no” miejscami w tekście.

find(), index(), count()

  1. Znajdź pozycję pierwszego wystąpienia „a” w słowie „banana”.
  2. Policz ile razy „a” występuje w „banana”.
  3. Sprawdź czy w zdaniu występuje słowo „Python”.
  4. Znajdź pozycję @ w adresie email.
  5. Policz ile razy słowo „test” występuje w tekście.
  6. Znajdź pozycję ostatniego wystąpienia „a” (użyj rfind).
  7. Sprawdź czy string zawiera jakąś cyfrę.
  8. Policz ile jest spacji w zdaniu.
  9. Znajdź wszystkie pozycje słowa „Python” w tekście.
  10. Sprawdź czy tekst zawiera któreś ze słów z listy zakazanych.

startswith(), endswith()

  1. Sprawdź czy plik kończy się na „.txt”.
  2. Sprawdź czy URL zaczyna się od „https://”.
  3. Sprawdź czy numer telefonu zaczyna się od „+48”.
  4. Filtruj listę plików – zostaw tylko .pdf i .doc.
  5. Sprawdź czy string zaczyna się cyfrą.
  6. Waliduj email – musi kończyć się na .com, .pl lub .org.
  7. Sprawdź czy zdanie zaczyna się wielką literą.
  8. Znajdź pliki graficzne (.jpg, .png, .gif).
  9. Sprawdź czy kod pocztowy zaczyna się od cyfr.
  10. Filtruj URLe – tylko te z „youtube.com”.

isdigit(), isalpha(), isalnum()

  1. Sprawdź czy string „123” składa się tylko z cyfr.
  2. Sprawdź czy string „Python” składa się tylko z liter.
  3. Sprawdź czy string „Python3” składa się z liter i cyfr.
  4. Waliduj kod pocztowy – 5 cyfr.
  5. Sprawdź czy PESEL składa się z 11 cyfr.
  6. Waliduj login – tylko litery i cyfry.
  7. Sprawdź czy string jest liczbą (isdigit()).
  8. Odfiltruj ze stringa wszystko co nie jest cyfrą.
  9. Sprawdź czy numer NIP składa się z 10 cyfr.
  10. Waliduj hasło – musi zawierać cyfrę.

Formatowanie

  1. Użyj f-stringa do wyświetlenia imienia i wieku.
  2. Sformatuj liczbę 3.14159 do 2 miejsc po przecinku.
  3. Wyrównaj tekst „Python” do 20 znaków (wyśrodkuj).
  4. Stwórz tabelkę z danymi używając f-stringów.
  5. Sformatuj cenę z separatorem tysięcy.
  6. Wyświetl procent z 2 miejscami po przecinku.
  7. Stwórz raport z wieloma danymi używając f-stringów.
  8. Dopełnij numer zerami do 5 cyfr (zfill).
  9. Sformatuj datę w różnych formatach.
  10. Stwórz fakturę używając f-stringów.

Zadania kompleksowe

  1. Napisz funkcję walidującą email (@, kropka, długość).
  2. Napisz funkcję sprawdzającą siłę hasła.
  3. Napisz funkcję formatującą numer telefonu.
  4. Napisz funkcję cenzurującą wulgaryzmy.
  5. Napisz funkcję skracającą tekst do N znaków + „…”.
  6. Napisz funkcję usuwającą duplikaty słów.
  7. Napisz funkcję zliczającą samogłoski i spółgłoski.
  8. Napisz funkcję sprawdzającą czy string jest palindromem.
  9. Napisz funkcję generującą inicjały.
  10. Napisz funkcję zamieniającą snake_case na camelCase.

Ćwiczenia dodatkowe – Regex

Podstawy regex

  1. Znajdź wszystkie cyfry w tekście „Python 3.12 jest świetny”.
  2. Znajdź wszystkie słowa w tekście (tylko litery).
  3. Znajdź wszystkie liczby całkowite w tekście.
  4. Sprawdź czy string zaczyna się od „Hello”.
  5. Sprawdź czy string kończy się na „.com”.
  6. Znajdź wszystkie słowa zaczynające się na „P”.
  7. Znajdź wszystkie słowa kończące się na „ing”.
  8. Policz ile razy występuje słowo „Python” (case-insensitive).
  9. Zamień wszystkie cyfry na „X”.
  10. Podziel tekst po przecinkach lub średnikach.

Walidacja

  1. Napisz funkcję walidującą email (prosty wzorzec).
  2. Napisz funkcję walidującą numer telefonu (9 cyfr lub XXX-XXX-XXX).
  3. Napisz funkcję walidującą kod pocztowy (XX-XXX).
  4. Napisz funkcję walidującą PESEL (11 cyfr).
  5. Napisz funkcję walidującą NIP (10 cyfr lub XXX-XXX-XX-XX).
  6. Sprawdź czy string to prawidłowy URL (http:// lub https://).
  7. Sprawdź czy string to prawidłowa data (DD-MM-YYYY).
  8. Sprawdź czy string to liczba całkowita (z opcjonalnym minusem).
  9. Sprawdź czy string to liczba zmiennoprzecinkowa.
  10. Waliduj hasło (min 8 znaków, wielka, mała, cyfra).

Ekstrakcja danych

  1. Wyciągnij wszystkie adresy email z tekstu.
  2. Wyciągnij wszystkie numery telefonów z tekstu.
  3. Wyciągnij wszystkie URLe z tekstu.
  4. Wyciągnij wszystkie hashtagi (#słowo) z tweeta.
  5. Wyciągnij wszystkie wzmianki (@użytkownik) z tweeta.
  6. Wyciągnij wszystkie daty w formacie DD-MM-YYYY.
  7. Wyciągnij wszystkie ceny (np. „19.99 zł”, „$50”).
  8. Wyciągnij wszystkie tagi HTML z tekstu.
  9. Wyciągnij nazwę użytkownika i domenę z emaila (grupy).
  10. Wyciągnij rok, miesiąc, dzień z daty (grupy).

Zamiana i czyszczenie

  1. Zamień wszystkie podwójne spacje na pojedyncze.
  2. Usuń wszystkie cyfry z tekstu.
  3. Usuń wszystkie znaki interpunkcyjne.
  4. Zamień daty z DD-MM-YYYY na YYYY-MM-DD.
  5. Zamień numery telefonów na format XXX-XXX-XXX.
  6. Cenzuruj słowa z listy (zamień na ***).
  7. Usuń wszystkie tagi HTML z tekstu.
  8. Zamień wiele białych znaków (spacje, taby) na jedną spację.
  9. Usuń numery z początku linii (np. „1. Punkt pierwszy”).
  10. Zamień wszystkie URLe na [LINK].