10.09.2010 Ob 05:18
Menu
· Domov
· Članki
· Forum
· Skripte
· Iskanje
· Kontaktirajte me
Aktualno na forumu
Zadnje teme
· Spletna trgovina
· ENOSTAVNO ZASLUŽITI ...
· Trogon d.o.o. išče Z...
· Zastonjski streznik
· OOP - Problem z prid...
Najbolj komentirane teme
· Moja stran [114]
· Izdelava majic [ ... [81]
· upload datotek [71]
· Gostovanje Pajek.Net [68]
· Postavitev server... [60]
Najnovejši članki
· Naprednejsi regex
· Regex za zacetnike
· CakePHP framework
· Progress bar v phpju
· Postavitev spletnega...
Anketa
Vam je všeč, da smo upgrejdali portal?









Za glasovanje morate biti prijavljeni.
Izmenjava
Število uporabnikov
· Št. online gostov: 1

· Št. online članov: 0

· Vseh članov: 712
· Najnovejši član: lega
Regex za zacetnike
Pameten moz je nekoc dejal "Zacetnik vidi problem in si rece: 'Oh to bom pa lahko z regexi naredil!', sedaj ima dva problema".
Ampak kljub temu so regexi zelo uporabni in resijo marsikateri drugace neresljiv problem ali pa vsaj kak problem mocno olajsajso, vendar pa je potrebno, ce se le da, iskati drugacno resitev, saj so regexi sami po sebi lahko izredno kompleksni in pocasni.

V tem clanku vam bom skusal predstaviti osnove regexov namigniti na to kako tezavno je dejansko spisati perfekten regex. Za zacetek naj povem kaj regex sploh je; regex je nekaksen napreden markup jezik za parsanje stringov, ki izhaja iz davnih casov racunalnistva, najbolj pa se je razvil pod okriljem perla. PHP podpira dve razlicni regex sintaksi, v tem clanku pa se bom omejil na perl kompatibilno, ker jo podpira veliko stevilo razlicnih jezikov in je v vecini primerov tudi hitrejsa.

V kombinaciji s perl kompatibilnimi regexi se v phpju uporabljajo funkcije:

  • preg_grep, ki iz arraya vrne vse ujemajoce stringe

  • preg_last_error, ki vrne zadnjo napako v regexu

  • preg_match_all, ki vrne vse ujemajoce podstringe iz stringa

  • preg_match, ki vrne prvi ujemajoci podstring

  • preg_replace_callback, ki preko callback funkcije naredi substitucije v stringu

  • preg_replace, ki zamenja ujemajoce podstringe z drugimi podstringi

  • preg_split, ki razdeli string po ujemajocih podstringih



Najpogostejsa raba regexov v php je verjetno preverjanje, ce je nek string ustreznega formata, za kar uporabljamo funkcijo preg_match in primeren regex. Npr:
[koda] if ( preg_match( '#^[a-z.]+@[a-z.]+$#i', $string ) )
{
// je e-mail
}else
{
// ni e-mail
}
?>[/koda]

Regex je bil v tem primeru #^[a-z.]+@[a-z.]+$#i,kar naj bi v grobem matchalo vse pravilne e-mail naslove (vendar jih ne, saj je to cela znanost in dejansko obstaja neka knjiga, kjer je opisana sestava pravega regexa za matchanje e-mailov). Oglejmo si ta preprost regex po vrsti:

  • # oznacuje zacetek ali konec regexa

  • ^ pomeni zacetek stringa, se pravi zahtevamo, da string matcha regex ze od vsega zacetka in ne sele nekje na sredini

  • [a-z.] je character class, ki ga oznacujeta oglata oklepaja, in matcha katerikoli znak od a do z in piko

  • + je kvantifikator, ki pomeni naj se, kar je pred njim, (se pravi [a-z.]) ponovi enkrat ali veckrat

  • @ je staticen del stringa in matcha afno

  • $ oznacuje konec stringa (tu se nahaja s podobnim namenom kot se je ^)



Ta regex bo za pravilne razumel vse maile, ki zgledajo nekako takole: janez.novak@gmail.com, ne bo pa matchal recimo janez.novak6@gmail.com. Pogosto uporabljan kvantifikator je tudi asterisk (*), ki matcha nic ali vec ponovitev, se pravi bi podobna koda:
[koda] if ( preg_match( '#^[a-z.]*@[a-z.]*$#i', $string ) )
{
// je e-mail
}else
{
// ni e-mail
}
?>[/koda]
za pravilne oznacila vse stringe, ki vsebujejo afno.

Kaj pa ce hocemo za pravilne brati samo maile iz domene gmail.com in yahoo.com? Potem bi regex izgledal nekako takole:

[koda] if ( preg_match( '#^[a-z]+@gmail.com$|^[a-z]+@yahoo.com$#i', $string ) ) ...
?>[/koda]

Znak | torej pomeni ali - podobno kot v normalni php kodi kjer v ta namen uporabljamo ||, da pa se izognemo nepotrebnemu pisanju lahko ta regex enakovredno napisemo takole:

[koda] if ( preg_match( '#^[a-z]+@(gmail.com|yahoo.com)$#i', $string ) ) ...
?>[/koda]

kjer je vse v oklepajih t.i. subpattern oz. podregex. Opazili smo ze, da zgornji regex v e-mail naslovih ne dopusca stevilk, ki pa so dokaj pogoste, zato lahko uporabimo naslednji trik:

[koda] if ( preg_match( '#^.+@(gmail.com|yahoo.com)$#i', $string ) ) ...
?>[/koda]

Tu smo character class zamenjali s piko, ki matcha katerikoli znak, se pravi ta regex res dopusca katerikoli e-mail z domen gmail.com in yahoo.com, verjetno je se celo prevec popoustljiv.

Vseskozi sem v primerih uporabljam tudi t.i. modifier #i. Modifierji spremenijo osnovno obnasanje regexa in jih napisemo za zakljucni znak regexa:


  • i pomeni, da regex enako tretira tako majhne kot velike crke

  • m regexu pove, da je string vecvrsticen, kar v osnovi pomeni samo, da ^ in $ ne oznacujeta zacetka/konca stringa, ampak zacetek/konec vsake vrstice

  • s pomeni, da pika matcha tudi newline znake, ki jih drugace iz zgodovinskih razlogov ne

  • x, ki omogoci ignoriranje vsega whitespace v regexu za lazjo berljivost

  • ter se nekaj drugih, ki po mojem mnenju ne sodijo v clanek za zacetnike



Druga zelo pogosta raba regexov v php pa je razbiranje podatkov iz stringa, kar ponavadi pocnemo s preg_match_all. Tako bi lahko za branje vseh datumov iz nekega besedila uporabili nekaj takega:

[koda] preg_match_all( '#([0-9]+)[^0-9]([0-9]+)[^0-9]([0-9]+)[^0-9]#', $besedilo, $matches );
?>[/koda]

kar bi napolnilo $matches array z vsemi podstringi iz stringa, tako da bi $matches[0], bil array vseh celih matchov, se pravi datumov, vsak naslednji index ($matches[1] do $matches[3]) pa bi bil array matchev vseh subpatternov iz oklepajev. Tako bi za datum 3/10/1928 dobili $matches array, ki bi zgledal nekako takole:

[koda] array(
[0] => array(
[0] => '3/10/1928'
),
[1] => array(
[0] => '3'
),
[2] => array(
[0] => '10'
),
[3] => array(
[0] => '1928'
)
)
?>[/koda]

Za razdelilnik med deli datuma smo v tem primeru uporabili kar character class [^0-9], ki matcha vse kar ni stevilka (^ v tem primeru negira character class). Vendar pa smo se s tako sestavo regexa mocno usteli, ker iz razlicnih razlogov matcha marsikaj, kar v resnici ni datum, saj matcha vse serije treh stevil, razdeljenih s po enim nestevilskim znakom ... tudi za matchanje datumov bojda obstajajo cele knjige.

S tem clankom sem vam zelel predstaviti nekaksne osnove za vstop v svet regexov, vec pa si lahko preberete v php manualu, ce pa vam bo kdaj dolgcas pa lahko obiscete tudi moj blog.
Komentarji
#1 | sobanu na 12.08.2008 ob 00:35
bravo, lepo napisano. Mogoče velja samo omeniti, da se za začetek in konec regexa lahko uporabi tudi druge znake, recimo v php manualu vidiš poleg # tudi | ter /.
#2 | Swizec na 12.08.2008 ob 14:45
Ja res lahko uporabis skoraj katerikoli znak, ki ni crka ali stevilka, vendar sem osebno ugotovil, da se najpogosteje uporablja #, ker ga redkokdaj uporabis v samem regexu. Ce uporabis nekaj bolj pogostega, recimo |, bi potem to kar naprej moral escajpati.
#3 | mtK na 23.10.2008 ob 10:54
Napačen link al tvoj blog ne dela? Grin
#4 | lank na 07.08.2010 ob 07:49
Most buy mbt shoes online think that they are buy mbt shoes above being supported by the town; but it often buy timberland boots happens that cheap timberland boots they are timberland boots not above supporting ghd glätteisen themselves by dishonest means. Sq
Pošlji komentar
Za komentiranje se morate prijaviti.
Ocene
Za ocenjevanje se morate prijaviti.

Zelo dobro Zelo dobro 100% [3 ocen]
Dobro Dobro 0% [ni ocen]
Povprečno Povprečno 0% [ni ocen]
Slabo Slabo 0% [ni ocen]
Zelo slabo Zelo slabo 0% [ni ocen]
Prijava
Uporabniško ime

Geslo



Še nisi član?
Klikni tu za registracijo.

Si pozabil geslo?
Ni problema, klikni tu in dobil boš novega.
Mini klepet
Za pošiljanje sporočil morate biti prijavljeni.

24.08.2010 ob 09:25
hi all!

29.07.2010 ob 16:19
ajmo ju3 vsi na SchengenFest Grin

18.06.2010 ob 20:58
Zdravo Iščem program ali pa kodo za drop down menu, katero vstavim v php stran narejeno z DW CS4. Takšno u izi in da lahko spreminjam barvo gumbov menijev in podmenijev oziroma zamenjam barvo gu

14.06.2010 ob 18:41
tnx vsem, sem zaključil pobiranje pri 1071 popolnoma izpolnjenih anketah Smile

08.06.2010 ob 16:40
@Profesor: hvala Wink pa tut anketo sm izpolnu Wink

08.06.2010 ob 14:39
če ima kdo čas (5 minut) in bi rad izvedel tudi koliko se česa pri plačevanju uporablja na spletu bi ga prosil za izpolnitev ankete (pišem diplomo): http://bit.ly/asrv
nd

08.06.2010 ob 14:38
@kraVa: eko Smile

05.06.2010 ob 23:17
@Profesor: Da Da Da Grin...eto Wink

02.06.2010 ob 21:46
Profesor, se absolutno strinjam da je še vedno poceni, sploh za tri dni... saj pravim, če ne bi bil takrat odsoten bi se je udeležil

02.06.2010 ob 20:02
se je samo zmanjšalo iz 10 na 5. Vam je bolj všeč, če jih je 10? 3x Da (kot na Talentih) pa bo nazaj Smile

Stran sprocesirana v 0.04 sekunde 1,682,223 različnih obiskovalcev