Resurs 

Introduktion till reguljära uttryck

Behandlar: Reguljära uttryck, hur de skrivs och tolkas.


Inledning

Reguljära uttryck är en notation som gör det möjligt att på ett mycket kompakt sätt göra sökmönster för mer avancerade saker än enkla ord. Exempelvis kan man beskriva alla stavningsvarianter av Carlzon, Carlsson, ... , eller alla sätt som datum kan skrivas på: 15 jan 2003, 030115, 03/15/01 etc. Den utmärkande egenskapen för ett reg.uttryck är att det "passar in" på flera olika varianter (av stavning, datum, osv.). reguljära uttryck är generella, kompakta sätt att beskriva det som är gemensamt för ett antal strängar.

Reguljära uttryck används i många kommandon och verktyg, ofta för att hitta ställen i en textfil där en viss text finns. Ibland också inte bara hitta den givna texten utan dessutom byta ut den mot något annat, t.ex. byta alla stavningsvarianterna ovan mot en enhetlig stavning "Karlsson". Att reg.uttryck används på många sätt har tyvärr medfört att det finns flera olika konkurrerande notationer för reguljära uttryck. Den ursprungliga notationen, som kallas Basala Reg.Uttryck (BRU), är inte så kraftfull, och den har därför utvidgats på olika sätt, för att man dels ska kunna använda  reg.uttryck i fler situationer, dels kunna skriva kortare, mer lättlästa reg.uttryck.

Förekomsten av flera olika notationssätt för reguljära uttryck gör det litet svårt att lära ut "reguljära uttryck", eftersom det egentligen inte finns en enhetlig standard. Det finns dock en notation, kallad Utvidgade Reg.Uttryck (URU), som är väldigt vanlig, och det är den som vi kommer att beskriva i denna artikel. Vi skriver dock bara "reg.uttryck" fastän vi med detta egentligen menar "utvidgade reg.uttryck". Då och då skriver vi dock ut hela frasen, för att påminna om att det är utvidgade (och inte basala) reg.uttryck vi beskriver.

Det finns också ytterligare påbyggnader till URU, bl.a den reg.uttrycksnotation som Perl (och numera Java) använder sig av. Vi kommer inte att gå in på dessa påbyggnader. Men det finns många notationer i omlopp, så du måste vara beredd på att nya verktyg, som du kan komma att stöta på i framtiden, kan ha annan notation för sina reg.uttryck. Verkligheten är tyvärr ofta mycket snårigare än vad man skulle vilja. Detta kan man inte skydda sig mot, bara vara mer eller mindre beredd på att hantera. Vi ska försöka bidra med en liten del, den del som handlar om utvidgade reguljära uttryck.

Den engelska termen för reguljära uttryck är Regular Expressions, vilket brukar förkortas exempelvis RE eller RegExp. Ibland används uttrycket 'en regexp' som synonym för ett reguljärt uttryck.

 

En första bekantskap med reguljära uttryck

Reguljära uttryck är egentligen bara ett kompakt sätt att räkna upp strängar, eller som det så fint heter, beskriva strängmängder. T.ex. så är

    [Hh]äls(a|ar|ning|osam)

bara ett kompaktare sätt att skriva mängden av följande strängar:

    Hälsa, Hälsar, Hälsning, Hälsosam, hälsa, hälsar, hälsning, hälsosam

Det som står inom hakparenteserna betyder att man får ta exakt ett av tecknen i denna s.k. teckenmängd. Därför kan vi ha strängar som börjar med antingen stort H eller med litet h. Här är hakparenteserna s.k. speciella tecken (metatecken), eftersom de inte står för sig själva utan har någon annan betydelse för notationssättet (i detta fall att markera en teckenmängd).

På samma sätt är tecknet | ett specialtecken, som liksom hakarna tillåter att man väljer mellan olika saker. I detta fall är det dock hela strängar man väljer, inte bara enstaka tecken som i teckenmängdens fall. Därigenom kan vi i vårt fall få strängar som slutar på a, ar, ning eller osam. Bokstäver som står utan hakar är inga specialtecken, och betecknar därför sig själva, såsom äls gör i det givna uttrycket. Alltså får vi möjligheterna:

    H     a
äls ar
h ning
osam

vilket är precis de kombinationer som vi skrivit ut i klartext ovan.

De mjuka parenteserna till sist är också specialtecken, men de används bara för att gruppera rätt. Hade vi inte haft parenteserna så hade reg.uttrycket tolkats annorlunda:

    [Hh]älsa|ar|ning|osam

skulle ha tolkats som följande strängar:

    Hälsa, hälsa, ar, ning, osam

Det finns fler specialtecken, men vi tar dem senare. Först ska vi visa hur nyttiga reguljära uttryck kan vara.

 

Vad man kan ha reguljära uttryck till

Tänk dig att du har ett stort antal textfiler, och att du vill hitta alla ställen i dessa filer där en person, som heter Karlsson, finns omnämnd. Problemet är bara att du är inte riktigt säker på hur han stavar sitt namn: är det Carlsson, Karlzon eller någon annan variant? Ska du behöva söka igenom filerna, först efter Carlsson, sedan gå igenom dem på nytt, men nu leta efter Karlzon, osv. ?

Det är givetvis slöseri med tid att inte leta efter alla varianter av Karlsson på samma gång, så de flesta sådana sökprogram, t.ex. grep på UNIX, tillåter dig att ge ett reguljärt uttryck som söksträng. I det här fallet skulle vi kunna söka efter alla ställen (för grep är detta detsamma som rader) där det står någon variant av Karlsson:

  /sw/gnu/bin/grep -E '[CK]arl(s|ss|z|sz)on'  textfil1 textfil2 ...

Här följer litet terminologi: man säger att grep skriver ut de rader som matchar det reguljära uttrycket, och det reguljära uttrycket kallas ett argument till grep.

 

Några specialtecken: ordgränsen, punkten och stjärnan

När man ger reguljära uttryck till grep så letar den upp de rader, där det reguljära uttrycket matchar någonstans på raden. Detta är mycket viktigt att komma ihåg. Om man t.ex. vill hitta alla rader, där ordet "att" finns, så kan man få följande träffar:

  /sw/gnu/bin/grep 'att'  textfil1 textfil2 ...

  Han hörde att hon var där.
  Det var natt och månen lyste.
  Batteristen i bandet var helt otrolig.

Detta beror just på att grep visar alla rader, som matchas någonstans: det står visserligen inte ordet "att" på andra raden, man där står "natt" och eftersom tecknen 'a', 't', 't' ingår i "natt", så matchar raden. Samma med rad tre där "att" ingår i ordet "batteristen". Vill man hitta "att" som helt ord, så måste man skriva det reguljära uttrycket annorlunda:

    \batt\b

Här är '\b' ett specialtecken, som betyder ordgräns, dvs. det matchar mellan en bokstav och en icke-bokstav (eller i omvänd ordning). Detta innebär t.ex. att '\ba' matchar bara då 'a':et föregås av blank, skiljetecken eller någon annan icke-bokstav. På samma sätt matchar 't\b' bara då 't':et har en icke-bokstav efter sig. Skulle det inte finnas något efteråt ('t' står sist på raden), så matchar '\b' ändå.

Observera att '\b' är något annorlunda än övriga specialtecken vi introducerat - den matchar ju inte mot något tecken, utan mot ett mellanrum, vilket är ovanligt. Observera också att '\b' ska ses som en enhet - det är bara ett tecken, även om vi är tvungna att använda två för att kunna skriva det: backslash + 'b'.

Hittills har vi bara sökt efter konkreta strängar eller ord. Hur gör man om man vill ha tag i alla ord, som slutar på "-ade", dvs kan vara verb i preteritum? Vi måste givetvis ha en ordgräns efter "-ade", men framför kan det ju stå vad som helst. Det finns förstås ett specialtecken för just denna situation. Detta tecken är punkten . och den matchar exakt ett tecken, men vilket som helst (utom newline-tecknet). Så om man vill hitta alla "-ade"-verb, som har, säg 6 bokstäver, så kan man skriva:

   \b...ade\b

Varje punkt matchar ett tecken, så det blir tre tecken matchade framför "-ade", därför sex-bokstaviga ord som slutar på "-ade". Observera att reg.uttrycket vet inget om verb i preteritum (det är du som ska veta), så det finns ingen garanti att reg.uttrycket ovan bara ger dig verb såsom träffar. Den kan t.ex. hitta en mening typ: "Lenin ligger på lit de parade i Kreml."

Men nu vill man ju inte bara hitta de sex-bokstaviga verben, utan alla verb oavsett längd. För denna situation behövs något sätt att säga, att vi vill ha . men inte tre, fyra, fem utan godtyckligt många. Det gör man i reguljära uttryck mha av en stjärna * (kallas Kleene's stjärna, efter den holländare som uppfann notationen för reguljära uttryck). Den matchar i sig inte några tecken, utan måste sättas efter något deluttryck. Därigenom markerar den att deluttrycket kan matcha 0, 1, 2, hur många gånger som helst. Observera dock att det inte behöver matcha någon gång alls: 0 antal gånger är tillåtet.

Vi kan nu få till ett bättre reg-uttryck för preteritum-verb:

  \b.*ade\b

som ska tolkas: ordet börjar, sedan följer .* dvs ett godtyckligt  antal tecken (0 går också), sist kommer "ade" och ordslut.

 

Kvotning och att söka efter metatecken

Backslash '\' är ett metatecken i sig. Ovan används backslash för att göra om 'b' till specialtecknet '\b' med betydelsen ordgräns.

När backslash sätts framför ett metatecken (exempelvis punkt) så blir detta tecken ett vanligt tecken. Detta används för att kunna söka även efter specialtecknena, och kallas för att "kvota" tecken (från eng. quote).

Låt oss säga att vi vill göra ett reg.uttryck som söker i programkod efter strängar som "variabel[4]" eller "data[0]". Det vi vill söka efter är små bokstäver följt av vänster hakparentes, en entalssiffra, och en höger hakparentes. Ett första försök skulle kanske bli:

    [a-zåäö]*[0-9]
Problemet här är att hakparanteserna redan har en betydelse - de anger teckenmängder. Man måste ta bort den speciella betydelsen hos hakarna för att få dem att beteckna sig själva. Det är detta man gör med backslashen.

Det korrekta reg.uttrycket ska vara:
    [a-zåäö]*\[[0-9]\]


Girighet hos reguljära uttryck

Tidigare använde vi vad som är ett mycket vanligt "idiom" inom reg.uttryck, nämligen .*, som används när man inte vet hur långt ord (läs: sträng) det är man söker. Tyvärr så ger obetänksamt användande av detta idiom upphov till en hel del felaktiga träffar. Detta beror på en egenskap som stjärnan * hos alla reguljära notationer besitter, nämligen s.k. girighet (eng. greedy matching). Kort förklarat så innebär det att stjärnan * "äter upp" så mycket den bara kan, ibland mer än vad man hade tänkt sig.

Låt oss säga att vi ska göra reg.uttryck som hittar taggar i en webbsidas html-kod. Vi vet att vi har följande i sidan (en länk följt av en tagg som ger en linje tvärs över sidan):

   <a href="http://www.ida.liu.se/"> IDA </a> <hr> Nyheter
och försöker göra ett reg.uttryck som hittar a-taggen:
   <a.*>
Detta fungerar dock inte riktigt som tänkt på grund av den giriga matchningen. Det som händer är att vi kommer hitta '<a' utan problem. Sedan tar '.*' över och matchar mot allting som finns på raden inklusive 'Nyheter' (girig, den tar allt!). Matchningen har fortfarande kvar att hitta tecknet '>', så systemet börjar gå bakåt tecken för tecken och lämna ifrån sig tecken från '.*' tills den hittar ett '>'.

Tyvärr så ger detta "giriga" matchingsförfarande att vi matchar för mycket med '.*'. Tanken med vårt reg.uttryck <a.*> var att det skulle matcha början och slut på samma html-tag, inte början på en tag och slutet på en annan. Om vi låter uttrycket ta hela raden och sedan backa tills det hittar '>' så har vi lyckats matcha till och med '<hr>'.

Hur skriver man ett reg.uttryck för att fixa detta då? Vissa notationer har varianter på icke-giriga matchings-tecken, men den generella lösningen ligger i vilka tecken man får "äta upp". Felet vi gör med .* är att vi kan gå förbi "slut-tecknet" >. Ett bättre alternativ till '.*' är uttrycket [^>]*, vilket betyder "matchar alla tecken utom just tecknet >". Därigenom riskerar vi inte att "äta upp" för mycket.

Skriver vi då hela vårt reg.uttryck:

    <a[^>]*>

så matchar det nu bara

    <a href="http://www.ida.liu.se/">

Allmänt tips: undvik '.*' Använd istället en mer specifik teckenmängd, där du explicit säger vilka tecken som tillåts: [ ... ]* eller vilka som inte är acceptabla: [^ ... ]*

 

Specialtecknen klammerparenteserna

Hur ska man göra om man vill leta efter rader, som innehåller, säg, ett telefonnummer, men vilket som helst. Låt oss säga att man vill hitta sex-siffriga telefonnummer med siffrorna i två-grupper, t.ex.:

   10 65 93        18 56 43        28 43 82

För att skriva ett reg.uttryck, som matchar ett par av siffror kan vi skriva:

   [0-9][0-9]

Inuti en teckenmängd (hakarna) kan man skriva ett bindestreck för att markera ett intervall. Det som står före bindestrecket måste då givetvis också komma före det som står efter: [9-0] är inte tillåtet. Ovanstående matchar vilket tvåsiffrig tal som helst, från 00 till 99, vilket kanske inte är riktigt rätt. Telefonnummer kan ju inte börja med en 0:a, så vi ändrar till det mer korrekta:

   [1-9][0-9]

För att få till ett reg.uttryck för ett helt telefonnummer så fortsätter vi bara att beskriva vilka tecken, som är tillåtna och i vilken ordning de ska komma:

   [1-9][0-9] [0-9][0-9] [0-9][0-9]

Observera att det står en blank efter första siffergruppen, likaså en efter andra gruppen.

Det där ser OK ut, men är litet långt. Vissa delar upprepar sig också (uttrycken för grupp 2 och 3 är identiska). Det finns ett specialtecken som kan användas då man har upprepade uttryck så här, nämligen krullparenteserna {}. Man kan skriva krullparenteser efter vilket deluttryck som helst i ett reg.uttryck. Man måste skriva en siffra inuti krullparenteserna, t.ex. {5}, vilket tolkas så att det deluttycket som står framför ska finnas exakt 5 gånger i reg.uttrycket.

Reg.uttrycket för ett telefonnummer kan nu skrivas litet kortare, eftersom vi vill ha exakt två siffror:

   [1-9][0-9] [0-9]{2} [0-9]{2}

Om man dessutom ser att deluttrycket: ' [0-9]{2}', dvs. blanktecken följt av 2 siffror, upprepas två gånger, så kan man skriva:

   [1-9][0-9]( [0-9]{2}){2}

Krullparenteserna kan hängas på på vilket deluttryck som helst, bara det är tydligt vilket deluttryck man avser. De mjuka parenteserna är till enbart för att gruppera ihop tecken, bl.a. så att man kan hänga på * och krullparenteser på deluttryck. Ovan säger rundparenteserna att det är "blanktecken följt av 2 siffror", som är det deluttryck som upprepas två gånger.

Det är tillåtet att inom krullparenteserna skriva inte bara en siffra utan två, t.ex. {2, 4}, vilket då innebär att deluttrycket får matcha 2, 3 eller 4 gånger. För att säga att ett deluttryck får matcha högst 2 gånger, kan man skriva {, 2}. Observera dock att kommatecknet måste finnas där. Analogt används {2,} då deluttrycket får matcha 2 eller fler gånger (hur många som helst).

Som vanligt gäller det att fundera på om mönstret kan ge träffar för mer än det man har tänkt sig. Exempelvis så kan kommandot

  /sw/gnu/bin/grep -E '[1-9][0-9]( [0-9]{2}){2}'  textfil

ge följande träff:

  Han dog 16 12 1978.

Hur kan det bli så? Igen måste man komma ihåg att grep hittar rader, där reg.uttrycket matchar någonstans. Och det är uppenbart att den delen av rader, som består av "16 12 19" uppfyller de villkor reg.uttrycket ställer. För att verkligen se till att du har exakt "2-siffor 2-siffor 2-siffor", så får du specificera mera i ditt reg.uttryck. Du får helt enkelt kräva att det som står efter de två sista siffrorna är något annat än en siffra. På samma sätt måste du säga att tecknet före första sifferparet inte är en siffra:

  [^0-9][1-9][0-9]( [0-9]{2}){2}[^0-9]

Här har vi använt specialtecknet "uppåtpilen" (eller "taket") ^, som måste stå först inuti en teckenmängd och i så fall har innebörden "komplement", dvs teckenmängden består av alla tecken, som inte är uppräknade inuti den. T.ex. så betyder [^0-9] alla tecken som inte är siffror.

Den här principen gäller allmänt. Vill du ha rader med exakt 2 vokaler efter varandra, så räcker inte [aeiouyåäö]{2}. Då får du även med rader, där det finns 3 vokaler i följd, för om t.ex. aou finns på raden, så finns ju ao på raden! Glöm inte att du får de rader där reg.uttrycket matchar någonstans.Tricket ligger i att sätta dit "barriärer" på sidorna om ditt reg.uttryck, så att det inte matchar mer än du vill. För att verkligen bara matcha exakt 2 vokaler, måste du kräva att det både framför och bakom vokalparet står något annat än vokal:

  [^aeiouyåäö][aeiouyåäö]{2}[^aeiouyåäö]

Allmänt tips: sätt "barriärer" på ditt reg.uttryck om det är möjligt, för undvika att rader, som bara matchar med "delar" (såsom ovan) inte oavsiktligt kommer med.

Sedan finns ytterligare en logisk kullerbytta, som man ofta gör här. Bara för att man begärt att få rader, som innehåller exakt två vokaler i följd, så betyder det inte att man inte kan få med rader, som har tre vokaler i följd. Även om man använder det bättre reg.uttrycket ovan! Hur är det nu möjligt? Igen så beror det på att matcharen  hittar rader där reg.uttrycket matchar någonstans. Följande rad matchas av det bättre uttrycket:

   Rouen ligger i Haute-Normandie i Frankrike.

Detta trots att den har tre vokaler i följd i "Rouen". Men den har  också exakt två vokaler i följd i "Haute", och eftersom det räcker med att vi får en match någonstans, så kommer raden med. Vårt reg.uttryck hittar alltså alla de rader, där det finns två vokaler i följd. Vad som i övrigt finns på dessa matchande rader har vi ingen aning om. Det finns ingen möjlighet att kontrollera hur raderna ser ut i övrigt, annat än att specificera i detalj hur en rad får se ut, från dess början till dess slut.

 

Specialtecknen för förankring: ^ och $

Ibland vill man inte att ett reg.uttryck ska kunna matcha var som helst på en rad. Man kanske vet att det man letar efter finns allra först på raden. I sådana situationer har man behov s.k. "ankare", specialtecken som "förankrar" reg.uttrycket till början av raden. För detta använder man uppåtpilen (denna gång står den utanför en teckenmängd, så den betyder inte komplementmängd), t.ex så matchar reg.uttrycket:

  ^Kog\.Vet\.

alla rader där tecknen "Kog.Vet." står först på raden.

Ett ankare för att markera slutet av raden finns också förstås, nämligen dollartecknet $, så reg.utttrycket nedan:

    ^ *$

matchar alla rader som är tomma eller bara består av blanktecken. Från början till slut ("^" och "$" står på ömse sidor) får nämligen bara finnas blanktecken. Det behöver inte finnas ett enda ("*" tillåter oss att matcha 0 förekomster), och det får finnas hur många blanka som helst, men det är också det enda som får finnas.

 

Specialtecken kortfattat

Det finns för varje reguljär notation två uppsättningar av specialtecken:

Om ett givet tecken är speciellt eller inte beror alltså på om man "befinner sig" inuti en teckenmängd  [ ] eller inte. T.ex. så är punkten ett specialtecken i ett reguljärt uttryck, men inte då den står inuti en teckenmängd. Där gäller andra regler.

Observera också att vissa tecken är speciella i båda dessa sammanhang, men har då olika betydelse. Detta gäller främst uppåtpilen ^, som inuti teckenmängd (då det står först i mängden) betyder "komplement", men i huvuduttrycket (också bara då den står först) betyder "matcha bara mot början av raden".

 

Tecken speciella inuti teckenmängder

Inuti teckenmängder är det bara tecknen ^ - (och egentligen också ]), som är speciella. Inte ens backslash är speciellt inuti en teckenmängd, så om man skriver t.ex.

    [\.\?\!]

för att försöka matcha punkt, frågetecken och utropstecken, så tolkas det man skrivit såsom

   [\.?!]

dvs, mängden av de fyra tecknen backslash, punkt, frågetecken och utropstecken. (Egentligen har vi skrivit en mängd med 6 separata tecken, men backslash-tecknet har upprepats tre gånger, vilket inte förändrar mängden. I en mängd kan samma element inte finnas med flera gånger, det kan bara ingå eller inte ingå.)

Var alltså noga med att skriva rätt tecken inuti teckenmängder, annars kan det hända att ditt reg.uttryck oavsiktligt matchar något du inte vill matcha. Detta är speciellt allvarligt när du använder reg.uttryck för att byta vissa strängar mot andra. T.ex. skulle

    sed  's/[\.?!]/SENTENCE_END/'  textfil
(Allting som matchar det reguljära uttrycket mellan de första snedstrecken byts ut mot texten mellan de sista snedstrecken)

felaktigt sätta in texten (markören) "SENTENCE_END" även där det står en backslash i textfilen. Medges att det är ganska ovanligt med backslash i filer, men det händer. Och just därför att det är ovanligt, så är det svårt att hitta sådana fel i ett skript.

Följande tecken är speciella (s.k. metatecken) inuti en teckenmängd:

^ markerar att vi vill ha komplementmängden, dvs. alla tecken utom de uppräknade
t.ex. [^a-zåäö] matchar varje tecken, som inte är bokstav
OBS! ^ måste stå som första tecken, annars tolkas det som vanligt tecken:  [abc^]
- markerar att vi vill ha ett intervall av tecken,
t.ex. [a-z] matchar en engelsk bokstav, [^0-9] matchar varje tecken utom en siffra
OBS! man kan få in ett bindestreck som vanligt tecken i en teckenmängd, om man skriver det sist: [abc-]
] markerar slutet på teckenmängden: den tolkas alltså speciellt av en teckenmängd,
OBS! man kan få in ett ] som vanligt tecken, men då måste det stå direkt efter [: []abc]

 

Tecken speciella i utvidgade reguljära uttryck (om de står utanför teckenmängder)

Följande tecken är speciella (s.k. metatecken) i ett reguljärt uttryck (gäller för URU):

. matchar mot exakt ett tecken, men vilket som helst (utom newline-tecknet)
t.ex. ...ar  matchar alla rader, som innehåller tecknen "ar", minst tre positioner in på raden
* markerar att det som står framför * kan upprepas på raden hur många gånger som helst, eller inte finnas alls
t.ex. a* matchar inget alls, a, aa, aaa, ... Vanligt "idiom":  .*  matchar godtycklig sträng, så lång som möjligt
\ används för att "kvota" specialtecken, så att de får tillbaka sin vanliga betydelse
t.ex.  \.[A-ZÅÄÖ] matchar en faktisk punkt följd av en stor bokstav.
Även att ändra vanliga tecken till olika meta-tecken, t.ex. ändra vanliga b till ordgränsen \b

 

Kortfattat om utvidgade reguljära uttryck

  . matchar mot exakt ett tecken, men vilket som helst (utom newline-tecknet)
t.ex. ...ar  matchar alla rader, som innehåller tecknen "ar", minst tre positioner in på raden
  * markerar att det som står framför * kan upprepas på raden hur många gånger som helst, eller inte finnas alls
t.ex. a* matchar inget alls, a, aa, aaa, ... Vanligt "idiom":  .*  matchar godtycklig sträng, hur lång som helst
  + matchar 1 eller flera av det som står före, dvs 1, 2, ...gånger, men inte 0 förekomster,
b+ matchar "b", "bb", "bbb", osv,  men det måste finnas minst 1 "b" för att b+ ska matcha
  ? "kanske"-match - matchar 0 eller 1 förekomst, dvs matchar högst 1 gång,
b? matchar "b" då det finns ett "b" och matchar tomma strängen "" annars
   {4} matchar ett givet antal gånger av det som står före:
{, 4} betyder högst 4, {4, } är minst 4 och {2, 4} är 2, 3, 4
b{4} matchar "bbbb",  b{2, 4} matchar "bb", "bbb" eller "bbbb"
  ^ matchar bara mot början av raden: alltså bara vettigt att skriva först i ett reg.uttryck (eller inuti teckenmängd)
^Han matchar bara en rad som börjar med tecknen  "Han", medan  ^ *$ matchar en rad som bara har blanka
  $ matchar bara mot slutet av raden: alltså bara vettigt att skriva sist i ett reg.uttryck
ande\.$  matchar bara en rad som slutar med tecknen  "ande."
 (      ) används bara för att gruppera ihop delar av ett reg.uttryck
( [0-9][0-9])  matchar precis samma som uttrycket inuti parenteserna gör
( | ) anger alternativ, dvs konstruktionen matchar antingen det ena eller det andra. OBS! Använd alltid parenteserna.
(adam|eva) matchar antingen "adam" eller "eva"
[   ] matchar exakt 1 av de tecken, som står uppradade inuti klamrarna,
t.ex. [aeiouyåäö] matchar en av vokalerna, [a-zåäö] matchar en gemen bokstav, vilken som helst
[^  ] matchar exakt 1 tecken, som inte står mellan klamrarna,
t.ex. [^aeiouyåäö] matchar en icke-vokal (en konsonant), [^0-9] matchar varje tecken utom en siffra
  \ används för att "kvota" specialtecken, så att de får tillbaka sin vanliga betydelse
t.ex.  \.[A-ZÅÄÖ]matchar en faktisk punkt följd av en stor bokstav
 \b markerar ordgräns, dvs början eller slut av ord. OBS! Matchar inte mot något tecken, utan mellan tecken
t.ex.  \b[a-zåäö]*ning\b matchar varje ord som slutar på "ning"