några sidor på nätet om PHP programmering

Sök efter  
Börja här Uppgifter Testa dig själv Tips Sidokarta mm. Länkar Sök

Vanliga HTML inriktade Regexp Regexp i PHP Övriga

1.9.3 Regexp

Vi har alla sökt i textsträngar efter delar. I VB använder vi då ofta mer eller mindre kreativa kombinationer av InStr och Mid. Istället kan man använda s.k. regular expressions (regexp) för sökningen.

Grunderna i Regular expressions

Ett litet exempel:

Vi vill kolla om en e-mail adress är något så när korrekt skriven. Vi vet att en mailadress alltid måste bestå av ett namn, ett @-tecken samt att domännamnet alltid har en punkt i sig. Denna punkt måste finnas efter @-tecknet, men det kan även finnas flera punkter.

Några exempel på mailadresser

fornamn.efternamn@firma.fi

namn@corporation.com

a123456@avdelning.firma.nu

 

Istället för att börja söka efter punkter, @ och andra tecken kan man istället skapa en "pattern" som skall motsvara detta. En möjlig pattern kan vara:

^([\w\.]+)@(\w+\.[\w\.]+)$

Man vad betyder då detta, och hur har vi kommit fram till denna sträng?

Enkla regexp

I sin enklaste form är en regexp bara ett ord. Nedan några exempel:

"test"

Kommer att matcha texter som innehåller "test" men även "testa", "testar", "jag testar" mm.

"top ten"

Kommer att matcha texten "top ten", men även "stop tension"

 

Metatecken

punkt (.)

. (punkt) har en speciell betydelse. Den matchar exakt ett tecken, vilket som helst. Detta gör att om man skriver:

"an.a"

så kommer detta att matcha bland annat "anna", men även "anka" samt "andas"

Om du uttryckligen vill söka efter en punkt så måste den citeras med \. Se nedanstånde exempel.

"3\.14" hittar 3.14
" 3.14" hiitar 3114, 3+14 mm. eftesom punkten betyder ett tecken

Frågetecken (?)

Matchar ett eller inget tecken. Exempel

"an?a"

Matchar "anna" och "anka" men även "ana". Matchar däremot inte "ankra" eftersom det var två tecken mellan n och a.

 

Stjärna (*)

Matchar 0, 1 eller flera upprepningar av föregående tecken. Exempel:

"an*a"

Matchar "ana", "anna" och "annnnnnnnnnna" , men inte "anka" eftersom det inte är n som upprepas. Man kan kombinera metatecknen. Exempel:

"an.*a"

Kommer att matcha "ana", "anna" men även "antag att du är hemma" eftersom vi säger att det kan finnas 0 eller flera av vilket tecken som helst.

 

Plus (+)

Som *, men tecknet måste finnas minst en gång. Se nedan:

"an.+a"

Kommer att matcha "anna", och "antillerna", men inte "ana" eftersom det inte kom något tecken mellan n och a

 

\d och \D

\d betyder en siffra 0 till 9. Följande är således möjligt:

"1\d"

Matchar "10", "11" ... "19", men inte "1a"

Genom att använda stor bokstav \D svänger man på betydelsen. \D betyder: inte en siffra.

"1\D"

Matchar "1A", "1+" ... "1Q", men inte "11" eler någun annan kombination som har en siffra efter 1:an

 

\w och \W

\w betyder en "normal bokstav", d.vs. inte %, ", &, mellanslag, tab, radbyte, o.dyl. \W (store W) betyder motsatsen: Följande är således möjligt:

"\w\W\w"

Matchar "a x", "Q<tabulator>a" och "1%2"

 

\s och \S

\s betyder ett mellanslag, tabulator eller radbyte ("white space"). Som vanligt svängs betydelsen om man använder stor bokstav, d.v.s \S betyder allt utom mellanslag, tab och radbyte.

"kalle\sanka"

matchar "kalle anka" men även "kalle<tabulator>anka", Matchar inte "kalle_anka"

Vill man vara på säkra sidan (det kan ju hända att någon slagit två mellanslag) skriver man: "kalle\s+anka" gör att säga att det kan vara ett eller flera mellanslag

 

\b och \B

\b beteckar ett ordbyte. \B betyder inte ordbyte.

"\bkalle"

matchar "kalle", "han heter kalle" och "kalleponken", men inte "bollkalle". \b skiljer sig från \s - som hittar "white space" - genom att \b även matchar början av strängen. "\skalle" kommer atta matcha "han heter kalle", men inte "kalleponken". Däremot matchar den " kalle". Såsom tidigare svängs betydelsen av stor bokstav.

"\Bkalle"

kommer att matcha "bollkalle" men inte "kalleponken"

{}

Som komplement till +, ? och * kan man även använda följande syntax:

"an{2}a"

matchar "anna" efersom n{2} betyder att det måste vara exakt 2 n

"a.{2}a"

matchar "abba" och "anna" efersom .{2} betyder att det måste vara exakt 2 stycken bokstäver (motsvarar "a..a")

"a.{2,6}a"

matchar "abba" och "anna", men även "antaga" efersom .{2,6} betyder att det måste vara mellan 2 och 6 tecken

|

Antingen eller. Se nedanstående exempel:

"kalle|anka"

matchar "kalle" och "anka".

[]

Intervall av tecken. Se nedanstående:

"1[3579]"

matchar "13", "15", "17" och "19" men inte "12"

"1[1-4]"

matchar "11", "12", "13" och "14" men inte "15"

 

Genom att sätta ^-tecken innanför [] svänger man om betydelsen:

"1[^1-4]"

matchar "1A", "15" men inte "11"

"1[^2345]"

gör att "12" ... "15" inte matchas

 

Innanför [] kan man inte sätta in andra metatecken och citering med \ är begränsat. De enda som är tillåtna att citera är \, [ och ].

"[\\\[\]]abc"

kommer att matcha alla strängar med fyra tecken som slutar med "abc" , och som börjar med \, [ eller ]

 

^ och $

Om man sätter ^ i början av en pattern säger man att det skall matchas från börkan av strängen.

"^kalle"

matchar "kalle" och "kalle anka" men inte "han hette kalle"

 

Sätter man $ i slutet säger man det skall matchas mot strängens slut

"kalle$"

matchar "han hette kalle" men inte "kalle anka"

 

Använder man en kombination så matchar man hela strängar

"^a.*a$"

Betyder att strängen måste börja med a och sluta med ett a

 

Några regexp exempel

IP nummer

IP nummer är alltid uppbyggda som siffra.siffra.siffra.siffra , d.v.s fyra tal 0-255 med punkt mellan.

 

En möjlig kontroll blir då:

"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$"

vilket betyder:

  1. Måste börja från början av strängen - ^ i början
  2. Måste komma 1-3 siffror - \d{1,3}
  3. Måste komma en punkt som nästa - \.
  4. Detta upprepas några gånger till
  5. Måste sluta efter sista siffran - $ i slutet

Detta gör följande resultat

IP Resultat
123.123.123.123 OK
123.211.222 Fel - en siffra för lite
a123.123.123.123 Fel - inte en siffra som första
123.123.123.123aaa Fel - inte en siffra som sista
999.999.999.999 OK enligt regexp - Helt fel i verkligheten

Elpost

En elpost adress har oftast förljande grundkonstruktion: namn@domain, t.ex. kalle@firma.fi

 

En enkel variant av kontroll kan då bli:

 

"^\w+@\w+\.\w+$"

Som betyder:

  1. Måste börja från början av strängen - ^
  2. Ett eller flera "normala" tecken - \w+
  3. Ett @ tecken
  4. Ett eller flera "normala" tecken - \w+
  5. En punkt - \.
  6. Ett eller flera "normala" tecken - \w+
  7. Strängen tar slut - $

Denna kontroll kommer att matcha "kalle@firma.com" men inte t.ex. "kalle@firma" (ingen punkt), eller "kalle.com" (inget @). Tyvärr kommer den även at fallera med "fornamn.efternamn@avdelning.firma.fi"

 

För att få denna adress att funka måste kan vi skriva t.ex. följande

"^[\w\.]+@\w+\.[\w\.]+$"

 

Vilket betyder:

  1. Måste börja från början av strängen - ^
  2. Ett eller flera tecken eller punkter - [\w\.]+
  3. Ett @ tecken
  4. Ett eller flera tecken - \w+
  5. En punkt - \.
  6. Ett eller flera tecken eller punkter - [\w\.]+
  7. Strängen tar slut - $

Ovanstående är inte helt perfekt. En bättre variant kanske kan vara:

"^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+@

[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.
[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$"

(Skall skrivas på en rad!)

 

   Börja härSträngarRegexp