-
Notifications
You must be signed in to change notification settings - Fork 84
Regex II
Regex užklausas Python'e tvarko modulis re. Prieš pradėdami darbą, nepamirškime importuoti:
import re
tarkime, kad dirbsime su telefono numeriais, tokiais kaip +370 642 12321. Iš pradžių reikia susikurti šabloną (regex objektą):
pattern = re.compile(r'\+370\s\d{3}\s\d{4}')
Kintamąjame pattern dabar turime objektą, kuris turi įvairių naudingų metodų iš re bibliotekos. Pirmas iš jų, kurį galime pabandyti yra search:
tekstas = '''Pirmas telefono numeris yra +370 123 12321, antras +370 321 10101.'''
res = pattern.search(tekstas)
print(res)
# <re.Match object; span=(28, 42), match='+370 123 12321'>
res dabar yra mūsų Match objektas. Atspausdinus jį matome, kad tekste yra šabloną atitinksnti simbolių seka, kurios pradžios indeksas 28, pabaigos 42(neįskaitant). Metodas ieško ir grąžina pirmą surastą reikšmę. Jei .search neranda mūsų šabloną atitinkančios simbolių sekos, gauname res įgauna None reikšmę. Tam, kad ištraukti match reikšmę, naudojame .group() metodą:
print(res.group())
# +370 123 12321
search metodas nepalaiko daugiau negu 1 reikšmės suradimo tekste, norint surasti visas, naudojamas metodas findall:
res = pattern.findall(tekstas)
print(res)
#['+370 123 12321', '+370 321 10101']
findall grąžina surastus atitikmenis sąraše.
Parašykime paprastą funkciją, kuri patikrintų, ar pateiktas el. pašto adresas atitinka standartus:
def validate_email(input):
email_regex = re.compile(r'^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$')
result = email_regex.search(input)
if result:
return True
return False
print(validate_email('[email protected]'))
print(validate_email('neteisingas@@email.lt'))
# True
# False
Įsivaizduokite, kiek Python kodo reikėtų, norint parašyti analogišką funkciją nenaudojant regex :)
Kaip gauti naudos iš grupavimo? Tarkime, turime vardų sąrašą tokiu formatu - Mr. Phil Collins. Parašykime funkciją, kuri išskaido kreipinį, vardą ir pavardę:
def split_names(name):
pattern = re.compile(r'^([A-Z]\w{1,3}\.)\s([A-Z]\w+)\s([A-Z]\w+)$')
result = pattern.search(name)
if result:
print(f'Visa eilutė: {result.group(0)}')
print(f'Kreipinys: {result.group(1)}')
print(f'Vardas: {result.group(2)}')
print(f'Pavardė: {result.group(3)}')
print('----------------------------------')
print(result.group())
print(result.groups())
else:
print('Įvestis neatitinka šablono')
split_names('Mr. Clint Eastwood')
# Visa eilutė: Mr. Clint Eastwood
# Kreipinys: Mr.
# Vardas: Clint
# Pavardė: Eastwood
# ----------------------------------
# Mr. Clint Eastwood
# ('Mr.', 'Clint', 'Eastwood')
Kaip matome, metodas group įvedus nulį grąžina visą eilutę, o toliau įvedant reikšmes nuo 1, paeiliui grąžina atskiras grupes. Tuščias group() veikia kaip ir group(0), o groups() grąžina grupes tuple masyve.
jeigu norime, grupėms galime suteikti savo pavadinimus, naudodami tokią sintaksę:
pattern = re.compile(r'^(?P<kreipinys>[A-Z]\w{1,3}\.)\s([A-Z]\w+)\s([A-Z]\w+)$')
print(f'Kreipinys: {result.group("kreipinys")}')
Šiuo atveju nereikia sukti galvos, kelintoje grupėje mūsų norimas rezultatas.
RegEx galime pasitelkti ir simbolių eilučių pakeitimams. Tam naudojamas metodas re.sub():
card_number = "card1: 0452 6544 0004 4456, card2: 1234 4567 8910 1112"
pattern = re.compile(r'\b\d{4}\s\d{4}\s\d{4}\s\d{4}\b')
res = pattern.sub('**** **** **** ****', card_number)
print(res)
# card1: **** **** **** ****, card2: **** **** **** ****
Jeigu norime palikti dalį originalios sekos, galime pasitelkti grupavimą, ir daryti taip:
card_number = "card1: 0452 6544 0004 4456, card2: 1234 4567 8910 1112"
pattern = re.compile(r'\b(\d{4})\s\d{4}\s\d{4}\s\d{4}\b')
res = pattern.sub('\g<1> **** **** ****', card_number)
print(res)
# card1: 0452 **** **** ****, card2: 1234 **** **** ****
pattern.sub metode nurodytas '\g<1> **** **** ****' argumentas yra mūsų pakeitimas, kuriame '\g<1>' yra pirma grupė mūsų šablone. Ją paliekame nekeistą. likusią dalį pakeičiame '*' simboliais. Antras argumentas yra tekstas su kuriuo dirbame.
#Flags
norėdami savo užklausoms pridėti papildomo funkcionalumo, galime naudoti flags.
Iš dažniau naudojamų reikėtų paminėti šias:
- re.IGNORECASE arba re.I - padaro jūsų užklausą case insensitive. t.y. nekreipia dėmesio, į didžiąsias - mažąsias raides.
- re.MULTILINE arba re.M - elgiasi su jūsų tekstu kaip su daug eilučių turinčia struktūra, o ne žiūri kaip į vieną eilutę.
- *re.VERBOSE arba re.X - leidžia jums suformuoti regex užklausą per kelias eilutes su komentarais. Prideda užklausoms skaitomumo.
flags naudojimo pavyzdžiai:
re.IGNORECASE:
tekstas = '''Trumpas tekstas
apie beleką'''
pattern = re.compile(r't\w+', re.I)
res = pattern.findall(tekstas)
print(res)
# ['Trumpas', 'tekstas']
Čia turime užklausą žodžių iš t raidės. Matome, kaip pridėjus re.I, rezultate gauname žodžius iš t ir T.
re.MULTILINE:
tekstas = '''Trumpas tekstas
apie beleką'''
pattern = re.compile(r'^\w+')
res = pattern.findall(tekstas)
pattern2 = re.compile(r'^\w+', re.M)
res2 = pattern2.findall(tekstas)
print(res)
print(res2)
#['Trumpas']
#['Trumpas', 'apie']
re.VERBOSE:
tekstas = 'Jonas Jonaitis +370 622 01234'
pattern = re.compile(r'''
[A-Z]\w+ # vardas
\s # tarpas
[a-z]\w+ # pavardė
\s # tarpas
\+370\s6\d{2}\s\d{5} # telefono numeris
''', re.X | re.I)
res = pattern.findall(tekstas)
print(res)
# ['Jonas Jonaitis +370 622 01234']
atkreipkite dėmesį, šiame pavyzdyje panaudojome dvi vėliavėles - jas tarpusavyje kombinuoti leidžia '|' simbolis.
Apie regex reikėtų žinoti , kad:
-
Nebūna 100% veikiančių regex užklausų, arba jos būna pernelyg ilgos ir visiškai neįskaitomos. Pvz. susiraskite oficialią regex užklausą e-mail adresams:)
-
RegEx yra labai plati tema, prirašyta nemažai storų knygų. Tai ką išmokome tėra pagrindai.
© Donatas Noreika ir Jotautas Treigys
Dekoratoriai
Iteratoriai ir generatoriai
RegEx
Pillow
NumPy
Pandas
- Pandas I
- Užduotys I
- Atsakymai I
- Pandas II
- Užduotys II
- Atsakymai II
- Pandas III
- Užduotys III
- Atsakymai III
Seaborn
Mašininis mokymasis
- 1 Tiesinės regresijos modelis
- 1 Užduotis
- 1 Atsakymas
- 2 Modeliai - klasifikatoriai
- 2 Užduotis
- 2 Atsakymas
- 3 Modeliai praktikoje
- 3 Užduotis (atnaujinta), atsakymas
- 3 Užduotis
- 3 Atsakymas (kodas su komentarais)
Requests, JSON, API
Web Scraping (Beautiful Soup)
Duomenų bazės
- SQL 1
- Užduotys
- Atsakymai
- SQL 2
- Užduotys
- Atsakymai
- SQL 3
- Užduotys
- Atsakymai
- SQL 4
- Užduotis
- SQL per Python
- Užduotis
- ORM 1
- Užduotys
- ORM 2
- Užduotis
- Atsakymas
Flask
- Įžanga
- Užduotys
- I dalis
- Užduotis
- I dalies kodas (atsakymas)
- II dalis
- Užduotis
- Atsakymas (kodas)
- III dalis
- Užduotis
- Atsakymas
- IV dalis
- Užduotis
- Atsakymas
- Flask Many2one, CRUD
- Flask One2many, many2many CRUD
- Flask: REST API kūrimas
- Flask: API su One2many (kodas)
- Flask: vartotojai
- Flask: nuotraukos pridėjimas, admin puslapis, puslapiavimas
- Flask: password reset, error pages
- Flask: projekto sutvarkymas
- Flask diegimas į serverį
Django
- 1. Įžanga, Modeliai
- 2. Administratoriaus svetainė
- 3. Šablonai
- 4. Views
- 5. Puslapiavimas, Paieška, Nuotraukos
- 6. Autorizacija
- 7. Vartotojai II, HTML laukai
- 8. Registracija, Formos
- 9. Vartotojo profilis
- 10. Create, Update, Delete rodinių klasės
- 11. Vertimai
- Užduotis: Autoservisas
- Biblioteka: kodas iki 6-tos dalies
- Biblioteka: kodas nuo 6-tos dalies
- Django diegimas į serverį
- Django diegimas į serverį 2
Django REST
Odoo
- Kurso programa: projektų valdymas
- 1 pamoka
- 2 pamoka
- 3 pamoka
- 4 pamoka
- 5 pamoka
- 6 pamoka
- 7 pamoka
- 8 pamoka
- 9 pamoka
Linux