Regelmessige uttrykk ved bruk av Python 3

Regelmessige uttrykk ved bruk av Python 3
Regelmessige uttrykk blir ofte sett på som denne virkelig obskure serien med hieroglyfer som man vanligvis kopierer fra Internett og pastes inn i koden hans. Denne mystiske trylleformularen viser da magiske evner til å finne mønstre i tekststrenger, og hvis vi spør det pent, vil det til og med gjøre oss fordel for å erstatte et gitt mønster i en streng med noe hyggeligere.

Når du for eksempel skriver håndterere for URL (og Gud hjelper deg hvis du skriver en fra bunnen av), vil du ofte vise det samme resultatet uavhengig av etterfølgende '/' i URL -en. E.g https: // eksempel.com/bruker/innstillinger/og https: // Eksempel.com/bruker/innstillinger bør begge peke på samme side til tross for etterfølgende '/'.

Du kan imidlertid ikke ignorere alle fremover -skråstrekene, som:

  1. Den fremre skråstreken mellom 'bruker' og 'innstillinger', e, 'bruker/innstillinger'.
  2. Du må også ta hensyn til '//' i begynnelsen av FQDN etterfulgt av 'https'.

Så du kommer med en regel som: "Ignorer bare de fremre skråstrekene etterfulgt av tomt rom.”Og hvis du vil ha, kan du kode den regelen med en serie if-ests-uttalelser. Men det vil bli tungvint ganske raskt. Du kan skrive en funksjon som sier Cleanurl () som kan innkapsler dette for deg. Men universet vil snart begynne å kaste flere kurveballer på deg. Du vil snart finne deg selv å skrive funksjoner for Cleanheaders (), ProcessLog () osv. Eller du kan bruke et vanlig uttrykk når det kreves noen form for mønstermatching.

Standard IO og filer

Før vi kommer inn på detaljene i vanlige uttrykk, er det verdt å nevne modellen som de fleste systemer har for tekststrømmer. Her er et kort (ufullstendig) sammendrag av det:

  1. Tekst behandles som en (enkelt) strøm av tegn.
  2. Denne strømmen kan stamme fra en fil med Unicode eller ASCII -tekst eller fra standardinngang (tastatur) eller fra en ekstern nettverkstilkobling. Etter behandling, si av et regex -skript, går utdata enten til en fil eller nettverksstrøm eller standardutgangen (e.G, konsoll)
  3. Strømmen består en eller flere linjer. Hver linje har null eller flere tegn etterfulgt av en ny linje.

For enkelhets skyld, vil jeg at du skal forestille deg at en fil er sammensatt av linjer som slutter med en Newline -karakter. Vi bryter denne filen til individuelle linjer (eller strenger) som hver slutter enten med en ny linje eller et normalt tegn (for den siste linjen).

Regexs og streng

En regex har ingenting, spesielt å gjøre med filer. Se for deg det som en svart boks som kan ta som en vilkårlig streng med en hvilken som helst (endelig) lengde, og når den når slutten av denne strengen, kan den enten:

  1. Godta strengen. Med andre ord, strengen fyrstikker Det vanlige uttrykket (regex).
  2. Avvis strengen, jeg.E, strengen gjør ikke det kamp Det vanlige uttrykket (regex).

Til tross for den svarte boksen-naturen, vil jeg legge til noen flere begrensninger til denne maskinen. En regex leser en streng sekvensielt, fra venstre mot høyre, og den leser bare ett tegn om gangen. Så en streng “Linuxhint” med bli lest som:

'L "i" n "u" x "h" i "n" t' [venstre til høyre]

La oss starte enkelt

Den mest forenklede typen regex ville være å søke etter og matche en streng 'C'. Det vanlige uttrykket for det er bare 'C'. Ganske trivielt. Måten å gjøre det på i Python vil kreve at du først importerer re modul for vanlige uttrykk.

>>> import re

Vi bruker deretter funksjonen RE.Søk(mønster, streng) hvor mønster er vårt vanlige uttrykk og streng I inngangsstrengen som vi søker etter mønsteret i.

>>> re.Søk ('C', 'Denne setningen har en bevisst C i seg')

Funksjonen tar inn mønsteret 'C', ser etter den i inngangsstrengen og skriver ut plasseringen (spenn) der nevnte mønster er funnet. Denne delen av strengen, denne substringen er det som samsvarer med vårt vanlige uttrykk. Hvis det ikke var noen slik kamp, ​​ville funnet at utdata ville være en Ingen gjenstand.

Tilsvarende kan du søke etter mønsteret 'Regular Expression' som følger:

>>> re.Søk (“Regelmessig uttrykk”, “Vi kan bruke vanlige uttrykk for å søke mønstre.)

re.søk (), re.match () og re.fullmatch ()

Tre nyttige funksjoner fra RE -modulen inkluderer:

re.Søk(mønster, streng)

Dette returnerer tilbake substringen som samsvarer med mønsteret, som vi har sett ovenfor. Hvis ingen kamp blir funnet da Ingen blir returnert. Hvis flere underlag samsvarer med et gitt mønster, er det bare den første forekomsten er rapportert.

re.kamp(mønster, streng)

Denne funksjonen prøver å matche det medfølgende mønsteret fra begynnelsen av strengen. Hvis det møter en pause et sted midtveis, kommer den tilbake Ingen.

For eksempel,

>>> re.Match ("Joh", "John Doe")

Hvor som strengen “Mitt navn er John Doe” er ikke en kamp, ​​og derav Ingen blir returnert.

>>> skriv ut (re.Match (“Joh”, “My Name Is John Doe”))
Ingen

re.fullmatch (mønster, streng)

Dette er strengere enn både det ovennevnte, og prøver å finne en eksakt match av mønsteret i strengen, ellers er standard for Ingen.

>>> skriv ut (re.fullmatch ("Joh", "Joh"))

# Alt annet vil ikke være en kamp

Jeg vil bruke bare re.Søk() Funksjon i resten av denne artikkelen. Når jeg sier at regex godtar denne strengen, betyr det at ate re.Søk() funksjonen har funnet en matchende substring i inngangsstrengen og returnert den, i stedet for Ingengjenstand.

Spesielle karakterer

Regelmessige uttrykk som 'John' og 'C' er ikke til mye bruk. Vi trenger spesialtegn som et spesifikt betyr i sammenheng med vanlige uttrykk. Her er noen eksempler:

    1. ^ - Dette samsvarer med begynnelsen på en streng. For eksempel vil '^c' samsvare med alle strengene som begynner med bokstaven C.
    2. $ - Dette samsvarer med slutten av linjen.
    3. . - Prikken er å indikere ett eller flere tegn, bortsett fra den nye linjen.
    4. * - Dette er til null eller mer karakter av det som gikk foran det. Så B* samsvarer med 0 eller flere forekomster av B. ab* matcher bare en, ab og en
    5. + - Dette er en eller flere karakter av det som gikk foran det. Så B+ samsvarer med 1 eller flere forekomster av B. ab* matcher bare en, ab og en
    6. \ - Backslash brukes som rømningssekvens i Regexes. Så det vil du ha et vanlig uttrykk for å søke etter den bokstavelige tilstedeværelsen av Dollar Symbol '$' i stedet for slutten av linjen. Du kan skrive \ $ i vanlig uttrykk.
    7. Krølle seler kan brukes til å spesifisere antall repetisjoner du vil se. For eksempel vil et mønster som AB 10 betegne strengen A etterfulgt av 10 B samsvare med dette mønsteret. Du kan spesifisere en rekke tall også, som B 4,6 samsvarer med strenger som inneholder B gjentatt 4 til 6 ganger etter hverandre. Mønsteret for 4 eller flere repetisjoner vil kreve bare et etterfølgende komma, som så B 4,
    8. Firkantede parenteser og utvalg av karakterer. Re som [0-9] kan fungere som en plassholder for ethvert siffer mellom 0 og 9. Tilsvarende kan du ha sifre mellom en og fem [1-5] eller for å matche hvilken som helst store bokstavbruk [A-Z] eller for en hvilken som helst bokstav i alfabetet uavhengig av at det er øvre eller småbruksbruk [A-Z].
      For eksempel hvilken som helst streng laget av nøyaktig ti sifre samsvarer med det vanlige uttrykket [0-9] 10, ganske nyttig når du leter etter telefonnumre i en gitt streng.
    9. Du kan opprette en eller lignende uttalelse, ved hjelp av | Karakter der et vanlig uttrykk består av to eller flere vanlige uttrykk, si, a og b. Regex a | b er en kamp hvis inngangsstrengen enten er en kamp for vanlig uttrykk a eller for b.
    10. Du kan gruppere forskjellige regexes sammen. For eksempel vil regex (a | b) c matche regexes for AC og

Det er mye mer å dekke, men jeg vil anbefale å lære når du går i stedet for å overbelaste hjernen din med mange obskure symboler og kantsaker. Hvis du er i tvil, er Python -dokumentene stor hjelp, og nå vet du nok til å følge dokumentene lett.

Hands på erfaring og referanser

Hvis du vil se en visuell tolkning av Regex -en din, kan du besøke Debuggex. Dette nettstedet genererer utsikt over Regex i sanntid og lar deg teste det mot forskjellige inngangsstrenger.

For å vite mer om det teoretiske aspektet av vanlige uttrykk, kan det være lurt å se på de første par kapitlene i introduksjonen til beregningsteorien fra Michael Sipser. Det er veldig enkelt å følge og viser viktigheten av vanlige uttrykk som et kjernekonsept for beregning i seg selv!