Python - Regularni izrazi (RegEx)


Regularni izraz (Regular Expression - RegEx) je sekvenca znakova koji definiše obrazac pretraživanja. Na primjer:

^a...s$

Gornji kod definiše RegEx obrazac. Uzorak je, bilo koji string od pet slova koji počinje s a i završava s. Uzorak definisan pomoću RegEx-a može se koristiti za podudaranje sa stringom.



Python ima modul pod nazivom re za rad s RegEx-om. Evo primjera:

import re

pattern = '^a...s$'
test_string = 'abyss'
result = re.match(pattern, test_string)

if result:
  print("Pretraga uspješna.")
else:
  print("Pretraga neuspješna.") 

Ovdje smo koristili funkciju re.match() za traženje uzorka unutar test_stringa. Metoda vraća objekt podudaranja ako je pretraživanje uspješno. Ako nije, vraća None.

Postoji još nekoliko funkcija definisanih u modulu re za rad s RegEx-om. Prije nego što to istražimo, naučimo same regularne izraze. Ako već znate osnove RegEx-a, pređite na Python RegEx.



Navođenje obrazac pomoću RegEx-a

Za specifikaciju regularnih izraza koriste se metaznakovi. U gornjem primjeru, ^ i $ su metaznakovi.


MetaCharacters

Metaznakovi su znakovi koje RegEx engine na poseban način tumači. Evo liste metaznakova:

[]. ^ $ * +? {} () \ |


[] - Uglate zagrade (Square brackets)

Uglatim zagradama naveden je skup znakova koje želite da se podudaraju.



Ovdje će se [abc] podudarati ako string koji pokušavate podudarati sadrži bilo koji od a, b ili c. Takođe možete odrediti raspon znakova pomoću - unutrašnjosti uglatih zagrada.

  • [a-e] -je isto što i [abcde].
  • [1-4] -je isto što i [1234].
  • [0-39] -je isto što i [01239].

Možete nadopuniti (invertisati) skup znakova upotrebom znaka ^ na početku uglate zagrade.

  • [^abc] - znači bilo koji znak osim a ili b ili c.
  • [^0-9] - znači bilo koji ne-cifreni znak.

. - Period

Tačka se podudara s bilo kojim pojedinačnim znakom (osim novog reda '\n').



^ - Caret

Simbol karete ^ koristi se za provjeru započinje li string s određenim znakom.




$ - Dollar

Simbol dolara $ koristi se za provjeru završava li string određenim znakom.




* - Star

Simbol zvjezdnice * podudara se s nula ili više pojavljivanja uzorka koji mu je preostao.




+ - Plus

Simbol plus + odgovara jednoj ili više pojava uzorka koji mu je ostavljena.




? - Question Mark

Simbol znaka pitanja ? podudara se s nulom ili jednom pojavom uzorka koji mu je preostao.




{} - Braces

Uzmite u obzir ovaj kod: {n, m}. To znači najmanje n, a najviše m ponavljanja uzorka koji su mu preostali.


Pokušajmo još jedan primjer. Ovaj RegEx [0-9]{2, 4} odgovara najmanje 2 karaktera, ali ne više od 4 karaktera.




| - Alternation

Okomita traka | koristi se za izmjenu (ili operator).



Ovdje se a|b podudara sa bilo kojim stringom koji sadrži ili a ili b.


() - Group

Zagrade se () koriste za grupiranje pod-obrazaca. Na primjer, (a|b|c) xz odgovara bilo kom stringu koji se podudara sa a ili b ili c iza čega slijedi xz.




\ - Backslash

Backlash se \ koristi za izbjegavanje različitih znakova, uključujući sve metaznakove. Na primjer, \$ podudara se ako string sadrži $ nakon čega slijedi a. Ovdje RegEx engine $ ne tumači $ na poseban način.

Ako niste sigurni ima li znak posebno značenje ili ne, ispred njega možete staviti \. Ovo osigurava da se karakter ne tretira na poseban način.


Posebne sekvence

Posebne sekvence olakšavaju pisanje uobičajenih obrazaca. Evo liste posebnih sekvenci:


\A - Podudara se ako su navedeni znakovi na početku stringa.




\b - Podudara se ako su navedeni znakovi na početku ili na kraju riječi.




\B - Suprotno od \b. Podudara se ako navedeni znakovi nisu na početku ili na kraju riječi.




\d - odgovara bilo kom decimalnom znaku. Ekvivalentno s [0-9].




\D - Podudara se s bilo kojim ne-decimalnim brojem. Ekvivalentno sa [^0-9].




\s - Podudara se kada string sadrži bilo koji razmak. Ekvivalentno s [ \t\n\r\f\v].




\S - Podudara se gdje string sadrži bilo koji znak koji nije razmak. Ekvivalentno s [^ \t\n\r\f\v].




\w - odgovara bilo kojem alfanumeričkom znaku (broju i slovu). Ekvivalentno s [a-zA-Z0-9_]. Inače, donja crta _ se takođe smatra alfanumeričkim znakom.




\W - odgovara bilo kojem ne-alfanumeričkom znaku. Ekvivalentno s [^ a-zA-Z0-9_].




\Z - Poklapa se ako su navedeni znakovi na kraju stringa.



Sada razumijete osnove RegExa , razgovarajmo o tome kako koristiti RegEx u vašem Python kodu.



Python RegEx

Python ima modul pod nazivom re za rad s regularnim izrazima. Da bismo ga koristili, moramo uvesti modul.

import re

Modul definiše nekoliko funkcija i konstanti za rad s RegEx-om.



re.findall()

Metoda re.findall() vraća popis stringova koji sadrži sva podudaranja.


Primjer 1: re.findall()

# Program za izdvajanje brojeva iz stringa
import re

string = 'hello 12 hi 89. Pozdrav 34'
pattern = '\d+'

result = re.findall(pattern, string) 
print(result)

# Ispisuje: ['12', '89', '34']

Ako obrazac nije pronađen, re.findall() vraća praznu listu.



re.split()

Metoda re.split() dijeli string tamo gdje postoji podudaranje i vraća listu stringova gdje je došlo do podjele.


Primjer 2: re.split()

import re

string = 'Twelve:12 Eighty nine:89.'
pattern = '\d+'

result = re.split(pattern, string) 
print(result)

# Ispisuje: ['Twelve:', ' Eighty nine:', '.']

Ako obrazac nije pronađen, re.split() vraća listu koja sadrži izvorni string. Možete prosljediti argument maxsplit metodi re.split(). To će biti maksimalni broj podjela.

import re

string = 'Twelve:12 Eighty nine:89 Nine:9.'
pattern = '\d+'

# maxsplit = 1
# podijeljen samo pri prvoj pojavi
result = re.split(pattern, string, 1) 
print(result)

# Ispisuje: ['Twelve:', ' Eighty nine:89 Nine:9.']

Inače, zadana vrijednost maxsplit-a je 0, što znači sve moguće podjele.



re.sub()

Sintaksa re.sub() je:

re.sub(pattern, replace, string)

Metoda vraća string gdje se podudarni događaji zamjenjuju sadržajem zamjenske varijable.


Primjer 3: re.sub()

# Program za uklanjanje svih razmaka
import re

# višeredni string
string = 'abc 12\
de 23 \n f45 6'

# odgovara svim razmacima
pattern = '\s+'

# prazan string
replace = ''

new_string = re.sub(pattern, replace, string) 
print(new_string)

# Ispisuje: abc12de23f456

Ako obrazac nije pronađen, re.sub() vraća izvorni string. Možete proslijediti count kao četvrti parametar metodi re.sub(). Ako je izostavljeno, rezultat je 0. To će zamijeniti sve pojave.

import re

# višeredni string
string = 'abc 12\
de 23 \n f45 6'

# odgovara svim razmacima
pattern = '\s+'
replace = ''

new_string = re.sub(r'\s+', replace, string, 1) 
print(new_string)

# Ispisuje:
# abc12de 23
# f45 6


re.subn()

re.subn() je sličan re.sub(), a očekuje se da vrati skup od 2 stavke koje sadrži novi string i broj izvršenih zamjena.


Primjer 4: re.subn()

# Program za uklanjanje svih razmaka
import re

# višeredni string
string = 'abc 12\
de 23 \n f45 6'

# odgovara svim razmacima
pattern = '\s+'

# prazan string
replace = ''

new_string = re.subn(pattern, replace, string) 
print(new_string)

# Ispisuje: ('abc12de23f456', 4)


re.search()

Metoda re.search() uzima dva argumenta: obrazac (pattern) i string. Metoda traži prvo mjesto na kojem obrazac RegEx daje podudaranje sa stringom. Ako je pretraga uspješna, re.search() vraća objekt podudaranja, a ako ne, vraća None.

match = re.search(pattern, str)

Primjer 5: re.search()

import re

string = "Python je zabavan"

# provjerite da li je 'Python' na početku
match = re.search('\APython', string)

if match:
  print("Uzorak pronađen unutar stringa")
else:
  print("Uzorak nije pronađen")  

# Ispisuje: Uzorak pronađen unutar stringa

Ovdje match sadrži objekt podudaranja.



Objekt podudaranja (Match object)

Možete dobiti metode i atribute podudarnog objekta pomoću funkcije dir(). Neke od najčešće korištenih metoda i atributa objekata podudaranja su:



match.group()

Metoda group() vraća dio stringa u kojem postoji podudaranje.


Primjer 6: Podudaranje objekta (Match object)

import re

string = '39801 356, 2102 1111'

# Trocifreni broj iza kojeg slijedi razmak nakon čega slijedi dvocifreni broj
pattern = '(\d{3}) (\d{2})'

# varijabla match sadrži objekt Match.
match = re.search(pattern, string) 

if match:
  print(match.group())
else:
  print("uzorak pronađen")

# Ispisuje: 801 35

Ovdje varijabla match sadrži objekt podudaranja. Naš obrazac (\d{3}) i (\d{2}) ima dva podskupa (\d{3}) i (\d{2}). Možete dobiti dio stringa ovih podgrupa u zagradama. Evo kako:

>>> match.group(1)
'801'

>>> match.group(2)
'35'
>>> match.group(1, 2)
('801', '35')

>>> match.groups()
('801', '35')


match.start(), match.end() i match.span()

Funkcija start() vraća index-s početka podudarnog podstringa. Slično tome, end() vraća index-s kraja podudarnog podstringa.

>>> match.start()
2
>>> match.end()
8

Funkcija span() vraća skup koji sadrži početak i kraj index-sa podudarnog dijela.

>>> match.span()
(2, 8)


match.re i match.string

Atribut re podudarnog objekta vraća objekt regularnog izraza. Slično, atribut string vraća prosljeđeni string.

>>> match.re
re.compile('(\\d{3}) (\\d{2})')

>>> match.string
'39801 356, 2102 1111'


Upotreba prefiksa r prije RegEx

Kada se r ili R prefiks koristi prije regularnog izraza, to znači sirovi string. Na primjer, '\n' znači da je novi red, dok r'\n' znači dva znaka: kosa crta \ iza koje slijedi n.

Backlash \ koristi se za izbjegavanje različitih znakova, uključujući sve metaznake. Međutim, upotreba prefiksa r tretira \ kao normalan znak.


Primjer 7: Sirovi string pomoću prefiksa r

import re

string = '\n i \r su izlazne sekvence.'

result = re.findall(r'[\n\r]', string) 
print(result)

# Ispisuje: ['\n', '\r']