Hvordan lage regulære uttrykk

Syntaksen i regulære uttrykk kan deles opp i flere grupper. I alt har vi 5 forskjellige. Disse kan vi si er

  • Tegnsetting
  • Ankrer
  • Klassekoder
  • Klasser
  • Modifiers

Disse gruppene dekker ikke alle felt, men de fleste. F.eks dekker de ikke hexadecimal som koden er \xTALL på.

Tegnsetting

Tegnsettingen er veldig essensielt i RegExp. De kan bestemme alt som skal foregå i et uttrykk.

  • \ » Den escaper andre tegn og klasser. Brukes forrann et annet tegn og du matcher tegnet. Bruker du den forrann klasser så blir det en annen sak, som vi kommer tilbake til. Eksempel: /(http:\/\/)/
  • | » Kan oversettes til eller. Eksempel: /(http|ftp):\/\//
  • { og } » Setter lengden den skal godta. Eksempel: /([\w]{10,20})/
  • ( og ) » Grupperer valgene og velger det en kan bruke senere. F.eks det som er mellom paranteser kan bli kalt med \\1 i en preg_replace. Eksempel: /([\w]{10,20})/
  • [ og ] » Setter klasser av tegn og rekkevidder. Eksempel: /[a-z]/
  • . » Alle tegn foruten \n Eksempel: /./
  • * » Matcher tegn fra 0 eller mer. Samme som {0,} Eksempel: /(.*)/
  • + » Matcher tegn fra 1 eller mer. Samme som {1,} Eksempel: /(.+)/
  • ? » Matcher tegn fra 1 eller ingen. Samme som {0,1} Eksempel: /(.?)/
  • ^ » Definerer starten på en streng.Eksempel: /^[a-z]{3,6}/ - Inneholder a-z på de 3-6 første tegnene av en streng
  • $ » Definerer slutten på en streng. Eksempel: /[a-z]{3,6}$/ - Inneholder a-z på de 3-6 siste tegnene av en streng

Ankrer

Ankerkoder vil definere hvor i strengen du mener. ^ og $ er to ankerkoder. Men det finnes flere.

  • \b » Setter en grense i et ord. Kutter ordet etter match.Eksempel: /MinStreng\b/
  • \B » Tar alt utenom grensenEksempel: /Rat\B/ - Tar Rattata, men ikke kun Rat.
  • \A » Definerer starten på en streng.
  • \Z » Definerer starten på en streng.

Klassekoder og klasser

Her er det som definerer rangen mellom strenger. Hvilke tegn den skal matche o.l. Det er flere måter å gjøre det på, bruke enkeltbokstaver med escape, f.eks \w og \d. Eller bruke range "manuelt", f.eks [a-z] og [0-9].

  • \d == [0-9] » Matcher alle tall
  • \D == [^0-9] » Matcher alle ikke tall
  • \w == [a-zA-Z_0-9] » Matcher alle bokstaver fra a til z, store og små. Samt tall og understrek.
  • \W == [^a-zA-Z_0-9] » Matcher alt som ikke er a-z (små og stort), tall og understrek
  • \s == [ \t\n\r\f] » Matcher whitespace, tabulater, newline osv.
  • \S == [^ \t\n\r\f] » Matcher alt som ikke er whitespace, tabulater, newline osv.

Modifiers

Jeg mangler et norsk ord på dette. Alle har hørt om det, men er ikke sikkert de er klar over alle eller vet hva de gjør. De fleste vet hva i-modifieren gjør, men har du hørt om o? Eller g? Eller kanskje e? Vel, her er en liste over modifiers.

  • i » Gjør mønsteret case-insensitive
  • e » Bruk som callback i preg_replace i PHP.
  • x » Bruk utvidet regulært uttrykk
  • o » Kjør uttrykket kun èn gang.
  • g » Kjør uttrykket globalt. Over flere ganger. Som preg_match_all()
  • m » Behandle uttrykket som flere linjer
  • s » Behandle uttrykket som kun èn linjer

Hvordan sette det sammen?

Så nå har vi all informasjonen vi trenger til å sette sammen et uttrykk. Slik som dette:

Eksempel

Vi skal stoppe spam, og har sett at et fellestrekk med spam-postene er at postene ofte har "Hey", "Hello" eller "Hi" i starten, og fulgt av to linker på neste linje. Den inneholder også tekst etter "Hey", "Hello" eller "Hi". Denne er observert som vanlig tekst mellom 14 og 25 tegn.

Eksempel på kommentar ser slik ut:

Hello! Great site, pal!
SpamLink | SpamLink

Vi skal lage et uttrykk som passer dette, hvordan?

Tenk et ledd om gangen. Først starter vi med at alle starter med "H". Da gjør vi slik:

/^H/i

Men siden det er et ord der, kan vi videreutvikle den og skrive slik:

/^H[^\s]{1,6}/i

Så hva har du mer av i strengen etter Hello/Hei/Hi? Jo, det kommer mellomrom og mer påfølgende tekst. Teksten kan være alle tegn utenom newline. Det kan skrives slik [^\n]. Og den teksten var mellom 14 og 25 tegn. Da utvider vi den og lar den bli slik:

/^H[^\s]{1,6}\s?[^\n]{14,25}/i

Grunnen til at jeg har \s? er for det skal være space, men eventuelt ikke. Derav er det ? etter \s, for å få valgfriheten.

Så kan vi tenke oss at et uttrykk for en link ser slik ut:


]?href="[^>]"[^>]?>(.*)< \/a>

Hvor det er a-tag og whitespace eller ikke, og attributten href="med link her". Verdien i href kan være alt utenom >. Så kan det være flere attributter, derav [^>]? før og etter href.

Samlet uttrykk

Så finner vi til slutt dette samlede uttrykket:

/^H[^\s]{1,6}\s?[^\n]{14,25}\n
]?href="[^>]"[^>]?>(.*)< \/a>(.*)?]?href="[^>]"[^>]?>(.*)< \/a>\s?$/i

  • Skriv ut artikkel
  • Abonner med RSS

Innhold