Regulaaravaldis

Regular expression

Regulaaravaldis

  • Regulaaravaldis (regular expression) kirjeldab ära mustri (pattern)
  • Mustrit saab kasutada otsinguks ja teksti asendamiseks
  • Võimaldab rohkem kui "otsi alamsõne X tekstist Y"

re moodul

import re

match = re.search("abc", "aabca")
print(match.group())  # abc is found in text
match = re.search("xyz", "aabca")
print(match is None)  # no match

  • Otsitakse mustrit "abc" tekstist "aabca"
  • re.search tagastab Match objekti, kus on täiendav info sees
  • Kui mustrit ei leita tekstist, tagastatakse None

Muster

  • Muster koosneb metamärkidest (erilise tähendusega sümbolid) ja tavalistest sümbolitest (otsese tähendusega)
  • Muster võib koosneda teistest (alam)mustritest
    • Kui A ja B on mustrid, siis ka AB, BA, AAB, ABB jne on mustrid
  • Alammustreid tavaliselt eraldatakse sulgudega: A((B)C)
  • Mustrile vastavat alamsõne tekstist nimetatakse vasteks

Mustri kasutamine

  • Mustrit saab kasutada:

    • et kontrollida, kas mingi sõne vastab reeglitele / mustrile (kas email on korrektne)
    • leida üles mingile mustrile vastav sõne (näiteks leida kõik emailid tekstist)

Muster kui alamsõne

  • Muster võib olla alamsõne, millele otsitakse täpset vastet tekstist
  • Üldiselt on sellisel juhul mõistlikum kasutada sub in text (kiirem)

Näide: "abc"

Sisalduv tekst: "aabca"

Mittesisalduv tekst: "ababac"

Suvaline sümbol

  • Vastab ühele suvalisele sümbolile
  • Muster: .

Näide: "a.bc"

Sisalduv tekst: "a2bca"
Sisalduv tekst: "aaubca"

Mittesisalduv tekst: "abc"

Algus

  • Tähistab sõne algust
  • Muster: ^

Näide: "^abc"

Sisalduv tekst: "abcd"

Mittesisalduv tekst: "aabc"

Lõpp

  • Tähistab sõne lõppu
  • Muster: $

Näide: "abc$"

Sisalduv tekst: "aaabc"

Mittesisalduv tekst: "abca"

0 või 1 kord

  • Eelnevat alammustrit on 0 või 1 kord
  • Muster: ?

Näide: "ab?c"

Sisalduv tekst: "aaca"
Sisalduv tekst: "aabca"

Mittesisalduv tekst: "aabbcc"

0 või rohkem kordi

  • Eelnevat alammustrit on 0 või rohkem korda
  • Muster: *

Näide: "ab*c"

Sisalduv tekst: "aaca"
Sisalduv tekst: "aabca"
Sisalduv tekst: "aabbbca"

Mittesisalduv tekst: "abab"
Mittesisalduv tekst: "bbc"

1 või rohkem kordi

  • Eelnevat alammustrit on 1 või rohkem korda
  • Muster: +

Näide: "ab+c"

Sisalduv tekst: "aabca"
Sisalduv tekst: "aabbbca"

Mittesisalduv tekst: "aac"
Mittesisalduv tekst: "abbba"

Varjestamine (escape)

  • Järgnevat erilist sümbolit tõlgendatakse ilma tähenduseta
  • Muster: \

Näide: "a\.bc"

Sisalduv tekst: "a.bc"

Mittesisalduv tekst: "a2bc"

Kordub m korda

  • Alammustrit kordub täpselt m korda
  • Muster: {m}

Näide: "ab{2}c"

Sisalduv tekst: "aabbcc"

Mittesisalduv tekst: "aacc"
Mittesisalduv tekst: "aabcc"
Mittesisalduv tekst: "aabbbcc"

Kordub m-n korda

  • Alammustrit kordub m - n korda
  • Muster: {m,n}

Näide: "ab{2,3}c"

Sisalduv tekst: "aabbcc"
Sisalduv tekst: "aabbbcc"

Mittesisalduv tekst: "aacc"
Mittesisalduv tekst: "aabcc"
Mittesisalduv tekst: "aabbbbcc"

Sobiv hulk

  • Sobivad sümbolid antud hulgast
  • Muster: [..]

Näide: "[ab]cd"

Sisalduv tekst: "acd"
Sisalduv tekst: "bcd"

Mittesisalduv tekst: "cd"
Mittesisalduv tekst: "ccd"

Sobiv vahemik

  • Sobivad sümbolid antud vahemikust
  • Muster: [.-.]

Näide: "[a-c]de"

Sisalduv tekst: "ade"
Sisalduv tekst: "bde"
Sisalduv tekst: "cde"

Mittesisalduv tekst: "de"
Mittesisalduv tekst: "dde"

Miinus hulgas

  • Miinusmärgi võib varjestada

Näide: "[a\-c]cd"

Sisalduv tekst: "acd"
Sisalduv tekst: "ccd"
Sisalduv tekst: "-cd"

Mittesisalduv tekst: "cd"
Mittesisalduv tekst: "bcd"

Miinus hulgas 2

  • Miinusmärgi võib panna esimeseks/viimaseks

Näide: "[ac-]cd"

Sisalduv tekst: "acd"
Sisalduv tekst: "ccd"
Sisalduv tekst: "-cd"

Mittesisalduv tekst: "cd"
Mittesisalduv tekst: "bcd"

Grupeerimine

  • Võimaldab grupeerida pikema alammustri
  • Muster: (...)

Näide: "(ab)?cd"

Sisalduv tekst: "acde"
Sisalduv tekst: "abcde"
Sisalduv tekst: "abbcd"

Mittesisalduv tekst: "ab"
Mittesisalduv tekst: "dde"

Või

  • Valik mustritest
  • Muster: |

Näide: "(ab|cd)+ef"

Sisalduv tekst: "abefg"
Sisalduv tekst: "cdefg"
Sisalduv tekst: "acdabefg"

Mittesisalduv tekst: "acef"
Mittesisalduv tekst: "abbef"

lookahead, lookbehind

  • (?=...), (?!...), (?<=...), (?<!...)
  • Kontrollivad, kas järgneb/eelneb märgitud muster
  • Ei "kasuta" vastet ära
    • avaldis "a(?=b)" kasutab sõnest "ab" ära vaid esimese sümboli
    • võrdluseks avaldis "ab" kasutab mõlemad ära
  • Võimaldavad keerukamaid kontrolle

Järgneb

  • Alammuster peab järgnema
  • Muster: (?=...)

Näide: "a(?=b)"

Sisalduv tekst: "aab"

Mittesisalduv tekst: "ac"
Mittesisalduv tekst: "aa"

Ei järgne

  • Alammuster ei tohi järgneda
  • Muster: (?!...)

Näide: "a(?!b)"

Sisalduv tekst: "ac"
Sisalduv tekst: "a"

Mittesisalduv tekst: "acb"
Mittesisalduv tekst: "b"

Eelneb

  • Alammuster peab eelnema
  • Muster: (?<=...)

Näide: "(?<=a)b"

Sisalduv tekst: "aabc"

Mittesisalduv tekst: "b"
Mittesisalduv tekst: "acb"

Ei eelne

  • Alammuster ei tohi eelneda
  • Muster: (?<!...)

Näide: "(?<!a)b"

Sisalduv tekst: "bc"
Sisalduv tekst: "acb"

Mittesisalduv tekst: "ab"
Mittesisalduv tekst: "aab"

Grupi kattumine

  • Saab kasutada eelnenud grupi kattumiseks
  • Muster: \1, \2

Näide: "(.+) \1"

Sisalduv tekst: "a ac"
Sisalduv tekst: "11 12"
Sisalduv tekst: "cc ccc"
Sisalduv tekst: "ab abc"

Mittesisalduv tekst: "aa"
Mittesisalduv tekst: "ab ba"

Tähed, numbrid, alakriips

  • Eriline sümbolite kogum
  • Muster: \w

Näide: "\w+a" ("[a-zA-Z0-9_]+a")

Sisalduv tekst: "1a"
Sisalduv tekst: "aa"
Sisalduv tekst: "babac"
Sisalduv tekst: "hi babac"

Mittesisalduv tekst: "a"
Mittesisalduv tekst: "a,a"
Mittesisalduv tekst: " a"

Tühik, tabulaator, reavahetus

  • Eriline sümbolite kogum
  • Muster: \s

Näide: "a\s{2}b"

Sisalduv tekst: "a  b"
Sisalduv tekst: "a\t bc"

Mittesisalduv tekst: "ab"
Mittesisalduv tekst: "a b"
Mittesisalduv tekst: "a   b"

Numbrid

  • Eriline sümbolite kogum
  • Muster: \d

Näide: "\d{2}"

Sama: "[0-9]{2}"

Sisalduv tekst: "12"
Sisalduv tekst: "a34c"
Sisalduv tekst: "a123"

Mittesisalduv tekst: "ab"
Mittesisalduv tekst: "1 2"
Mittesisalduv tekst: "a2"

Ei kuulu hulka

  • Sümbolid, mis ei tohi vastes olla sellel positisoonil
  • Muster: [^..]

Näide: "[^a-c1-3]x"

Sisalduv tekst: "4x"
Sisalduv tekst: "ayxc"

Mittesisalduv tekst: "ax"
Mittesisalduv tekst: "1x"
Mittesisalduv tekst: "cx"

Süntaks

  • Kui muster kasutab kurakaldkriipsu (\), tuleb see kirjutada:
    • "\\\\" või
    • r"\\"
  • r"" - raw string notatsioon
  • Tavalises sõnes tuleb kurakaldkriipsu jaoks kasutada kahte sümbolit "\\", seejärel saab juurde lisada regulaaravaldise sümboli (näiteks "d")

raw string

import re

text = "backslash: \\"
print(text)  # backslash: \
print("match" if re.search("\\\\", text) else "no match")
# match
print("match" if re.search(r"\\", text) else "no match")
# match
print("match" if re.search("\\", text) else "no match")
# error
  • Viimane annab vea, muster tõlgendab \\ kurakaldkriipsuna, millega saab varjestada erisümboleid. Erisümbolit aga ei järgne.

raw string

import re

print("match" if re.search("(.)\1", "aa") else "no match")
# no match, why?
print("match" if re.search("(.)\\1", "aa") else "no match")
# match
print("match" if re.search(r"(.)\1", "aa") else "no match")
# match

  • Esimeses \1 on läheb regulaaravaldise jaoks arvesse ühe sümbolina
  • Teisel real \\ läheb arvesse \ märgina, millele järgneb grupi number

Grupid

import re

match = re.search("xk(ab)?(cd)", "xkcde")
print(match.group())
print(match.group(0))
print(match.group(1))  # None. why? for "(ab)"? 
print(match.group(2))  # for "(cd)"
  • group tagastab vaste sulgudest
  • group(0) tagastab kogu vaste
  • group(1) tagastab 1. sulu vaste jne

Grupid

import re

match = re.search("(?:ab)?(cd)e", "acde")  # (?:...) 
print(match.group())
print(match.groups())  #  ('cd')

match = re.search("(ab)?(cd)e", "acde")
print(match.group())  # cde
print(match.groups())  # (None, 'cd')
  • (?:...) tähistab vastet mittetagastavat gruppi
  • .groups() tagastab kõik erinevad grupid
  • Ülemises esimeste sulgude vastet ei otsita
  • Teises esimeste sulgude vastet ei ole
  • match() otsib sõne algusest
  • search() otsib tervest sõnest
import re

m1 = re.match("c", "abcdef")
m2 = re.search("c", "abcdef")

print("Match" if m1 is not None else "No match")
# No match
print("Match" if m2 is not None else "No match")
# Match
  • Esimene prindib "No match" - otsib algusest
  • Teine prindib "Match"

findall()

  • findall() tagastab mittkattuvate vastete (sõnede) järjendi
  • finditer() tagastab iteraatori Match objektidest
import re
text = "tere minu@email.ee, sõbra email on guido@baggins.com ja guits@bag.com"

emails = re.findall(r"[\w.-]+@[\w.-]+", text)
for email in emails:
    print(email)

for email in re.finditer(r"[\w.-]+@[\w.-]+", text):
    print(email.group())
  • emails on järjend kõikidest vastetest
  • finditer tagastab iteraatori, elemente tagastatakse vastavalt vajadusele

Viiteid