Spring til indhold

Regulært udtryk

Fra Wikipedia, den frie encyklopædi
For alternative betydninger, se Udtryk (flertydig). (Se også artikler, som begynder med Udtryk)

Et regulært udtryk (oversat fra engelsk, regular expression, ofte forkortet til regexp eller regex) er en følge af tegn, der definerer et mønster til søgning/matchning. Det bruges ved søgning af tekststrenge i tekster (herunder søg og erstat), og i leksikalsk analyse. Mange programmeringssprog har understøttelse for regulære udtryk til manipulering af tekststrenge. Unix hjalp i stort omfang med at gøre regulære udtryk kendte igennem programmer som sed og grep.

Blandt pionererne inden for området er Stephen Cole Kleene og Ken Thompson.

Et regulært udtryk, også kaldet et mønster, er et udtryk som beskriver en mængde af tekst som mønsteret passer til. De kan være nyttige når man skal afgøre om en tekststreng tilhører en godkendt mængde, når man vil søge efter mønsteret for en delstreng i en større tekst, eller hvis man desuden vil erstatte dele af en tekststreng med en anden.

Regulære udtryk har en syntaks hvor tegn er delt op i almindelige tegn, der betyder hvad der står, og metategn, der har særlige betydninger. Der findes flere dialekter inden for regulære udtryk som afgør hvilke tegn der er specielle. Nedenfor er en dialekt givet som er kompatibel med flere implementeringer som benyttes i moderne programmeringssprog.

De almindelige tegn

[redigér | rediger kildetekst]

De almindelige tegn er lettest. Det regulære udtryk, Hejsa er netop det:
en sekvens af fem tegn, hvor det første er et H, det næste er et e og så videre. Det er således underordnet hvad der kommer foran eller bagved de fem tegn. Udtrykket Hejsa matcher således med tekst som indeholder Hejsan og med Hejsa!, men derimod ikke hejsa, da der er afhængighed af om det er med stort eller småt – se afsnittet Tegnklasser nedenfor. Alle alfanumeriske tegn er almindelige tegn. Bogstaver uden for ASCII-tegnsættet, som æ, ø og å er desuden også, og det samme gælder for andre ikke-engelske bogstaver.

Metategn benyttes til at beskrive en serie af tegn, snarere end enkelte tegn. Uden metategn var vi kun i stand til at beskrive ordrette sætninger, men med metategn kan vi beskrive sætninger ud fra mere abstrakte kriterier. Lad os starte med de simpleste metategn:

Punktum ( . )
Et punktum betyder et enkelt af hvilket som helst tegn, dog ikke "ny linje" (\n eller New Line).
Asterisk ( * )
En asterisk betyder nul eller flere af det forgående tegn og forudsætter derfor at den følger efter noget gyldigt. .* betyder for eksempel nul eller flere af hvilket som helst tegn og a* betyder nul eller flere a'er.
Plus ( + )
Et plus virker næsten som asterisken, men betyder en eller flere af det forgående tegn. Forskellen her ligger i at et regulært udtryk som a* faktisk passer til tekststrengen bbbbbb siden der er nul eller flere a'er. a+ ville kræve mindst ét a.
Spørgsmålstegn ( ? )
Et spørgsmålstegn betyder nul eller ét af det forgående tegn.
Cirkumfleks ( ^ )
En cirkumfleks er et ankertegn der svarer til starten af en streng eller en linje. Den svarer ikke til noget tegn men den forankrer det efterfølgende tegn. kat vil svare til alle strenge hvor sekvensen kat indgår et eller andet sted. ^kat vil derimod kun passe hvis sekvensen kat er det første.
Dollartegn ( $ )
Et andet ankertegn der svarer til enden af en streng eller en linje.
Omvendt skråstreg ( \ )
En Omvendt skråstreg bruges til at udtrykke et metategns normale værdi, dvs. hvis man gerne vil udtrykke en rigtig asterisk, skal man bruge \*. tegn kan desuden være en oktalværdi eller en hexadecimalværdi, så man kan udtrykke alle tegn. Det gøres eksempelvis som \020 for mellemrum. Dette er praktisk for tegn som ikke normalt kan udskrives.
Kontroltegn der kan være svære at skrive og repræsentere, er også markeret med en omvendt skråstreg.
regex navn ASCII oktal
\a alert <BEL> \007
\b backspace <BS> \010
\e escape <ESC> \033
\f form feed <FF> \014
\n new line[1] <LF> \012
\r carriage return[2] <CR> \015
\t tab <HT> \011
\v vertical tab <VT> \013
Lodret streg ( | )
En lodret streg angiver et alternativ mellem 2 regulære udtryk på hver side af den. Det regulære udtryk Hans|Grethe svarer til Hans eller Grethe. Et typisk eksempel er når man skal tage højde for forskelle mellem Engelsk og Amerikansk stavemåde, f. eks grey|gray.
Gruppering med runde parenteser
Gruppering bruges ofte sammen med alternativer. Hvis man vil se dato, emne og afsender i en e-mail, kan man se dem i hoveddelen. En header er kendetegnet ved et navn der står først på en linje og er efterfulgt af et kolon (:). Det regulære udtryk bliver ^(Date|Subject|From):.

[] markerer en tegnklasse. [aA] svarer til et tegn der er enten a eller A. [abcd] svarer til et af bogstaverne a, b, c eller d. Det er også muligt at angive et værdiområde. [0-9] svarer til alle tallene mellem 0 og 9 og [a-z] svarer til de små bogstaver på engelsk. Det er også muligt at kombinere flere værdiområder i samme tegnklasse, som f. eks [a-fA-F0-9] der svarer til et heksadecimaltal. Bindestregen er et metategn i tegnklassen, undtagen når den står først, [-a-z] svarer således til et lille bogstav eller en bindestreg.

Et andet metategn i tegnklasser er cirkumfleksen (^), men kun når den er det første tegn. Betydningen af den er negation af hele tegnklassen. [^abcd] svarer så til alle andre tegn end a, b, c og d.[3] Som et eksempel vil det regulære udtryk <[^>]*> svare til et tag i HTML og vil kunne bruges til at fjerne al markup fra HTML for at præsentere det som ren tekst.

I POSIX standarden er der defineret nogle specielle tegnklasser, der simplificerer håndteringen af sprogafhængige detaljer. Eksempelvis svarer [[:lower:]] til [a-z] med engelske indstillinger, mens det svarer til [a-zæøå] med danske indstillinger.

[:alnum:] bogstaver og tal
[:alpha:] bogstaver
[:blank:] mellemrum og tabulatortegn
[:cntrl:] kontroltast
[:digit:] ciffer
[:graph:] synligt tegn pånær mellemrum
[:lower:] småt bogstav
[:print:] synligt tegn samt mellemrum
[:punct:] grammatisk tegn ('.', ';', ',' etc.)
[:space:] usynligt, grammatisk tegn (mellemrum, linjeskift etc.)
[:upper:] stort bogstav
[:xdigit:] hexadecimal ('a0', 'ff', '7c' etc.)

Da ovenstående klasser kan virke uelegante, er der udviklet nogle tilsvarende stenografiske notationer:

\d tal
\D alt andet end tal
\w bogstaver og tegn der kan være del af et ord
\W tegn der ikke kan være del af et ord
\s whitespace tegn - mellemrum og linjeskift mm.
\S grafiske tegn - ikke whitespace

Matematikeren Stephen Cole Kleene indførte regulære set (regular sets) i algebra, og regulære udtryk som notationen for at udtrykke dem.

UNIX teksteditoren ed var et af de første computerprogrammer der udnyttede regulære udtryk. Snart fulgte programmet grep der er et specialiseret tekstsøgnings program.

I 1986 blev 2 typer regulære udtryk defineret i POSIX standarden.

  • Basic Regular Expressions er typen brugt i ed; den regnes generelt for forældet, men mange programmer understøtter den af hensyn til bagudkompatibilitet.
  • Extended Regular Expressions hvor metategnene plus (+) og spørgsmålstegn (?) indføres, og brugen af Omvendt skråstreg ikke er nødvendig ved parenteser.

Programmeringssproget perl har udviklet en avanceret version af regulære udtryk, og i dag taler man ofte om Perl Compatible Regular Expressions – PCRE, som mere eller mindre er blevet implementeret i bl.a. .Net og Java (efter version 1.4).

Praktisk anvendelse

[redigér | rediger kildetekst]

Regex bliver ofte brugt i selv de mest simple programmer skrevet i Perl, men finder sin generelle anvendelse når der skal forekomme parsning/analyse af tekst (f.eks. i programmer som Emacs eller vi-editoren). Et eksempel kunne være at sikre sig at brugere ikke indtastede ulovlige (eller uønskede) værdier i en formular på internettet eller i et program – så problemer som f.eks. SQL-injektions kan nemt kan undgås (ved f.eks. kun tillade bogstaver og tal: [a-zæøåA-ZÆØÅ0-9])

  1. ^ På en Mac vil \n ofte svare til carriage return.
  2. ^ På en Mac vil \r ofte svare til line feed.
  3. ^ Hvorvidt linjens afsluttende linjeskift bliver regnet med afhænger af implementationen.

Eksterne henvisninger

[redigér | rediger kildetekst]
Spire
Denne artikel om datalogi eller et datalogi-relateret emne er en spire som bør udbygges. Du er velkommen til at hjælpe Wikipedia ved at udvide den.