10.09.2010 Ob 05:26
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: 2

· Št. online članov: 0

· Vseh članov: 712
· Najnovejši član: lega
Naprednejsi regex
Prva stvar, ki bi jo rad omenil pri naprednih regexih je, da popoln regex ne obstaja, vedno se najde kak, ki je se natancnejsi, se hitrejsi, se preprostejsi ... zato se gre tu vecinoma za najboljsi priblizek kar ga lahko najdemo v danem casu.

Pomemben del phpjeve regex podpore je podpora unicode lastnosti znakov, ki jo omogocimo z modifierjem u. Te lastnosti nam pomagajo pri matchanju vseh crk, vseh stevil ipd., ker pac ne moremo predvideti kateri vsi znaki so velika tiskana crka v vseh jezikih. V regexu te lastnosti oznacimo z p{xx}, kjer xx predstavlja lastnost npr. L za crko (letter). Spisek vseh lastnosti si lahko ogledate na tu ali pa v php manualu pri opisu regexov. Te lastnosti negiramo z uporabo velikega p: P{xx}, vendar mi je osebno ljubsi podoben nacin kot negiranje character classa p{^xx}, ki v php manualu ni omenjen kot podprt vendar je (vecina regex interpreterjev tega ne podpira, poleg phpja vem samo se za perl). V opozorilo vsem, ki se bavijo z razlicnimi jeziki: Python unicode lastnosti sploh ne podpira.

Drug zelo pomemben del naprednejsega pisanja regexov pa je natancno oznacevanje stevila ponovitev v zavitih oklepajih (namesto + in * kvantifikatorja) po kljucu {min, max}. Primer:

[koda]
// matcha vse skupke pet crk
preg_match_all( '#p{L}{5}#u', $besedilo, $besede );

// matcha vse skupke vsaj pet crk
preg_match_all( '#p{L}{5,}#u', $besedilo, $besede );

// matcha vse skupke od ene do petih crk
preg_match_all( '#p{L}{1,5}#u', $besedilo, $besede );

// proti pricakovanjem NE matcha do pet crk ampak razume {,5} kot dobeseden string
preg_match_all( '#p{L}{,5}#u', $besedilo, $besede );

?>[/koda]

Velikokrat se v regexih uporabljajo tudi t.i. backreference, ki nam omogocajo, da v regexu uporabimo prej matchan subpattern ali del matcha uporabimo v zamenjavi. Tako bi lahko html stripali nepotrebnih tagov nekako takole:

[koda]
$input = preg_replace( '#<([a-z]+).+?>(.*?)#i', '$2', $input );

?>[/koda]

Kot lahko vidite smo tu najprej uporabili backreference v regexu in tako poskrbeli, da se zapirajoci html tag ujema z odpirajocim, v zamenjalnem stringu pa smo backreference uporabili, da smo namesto celotnega matcha vstavili samo osrednji del.

Ampak kaj ce hocemo zamenjati vse tage razen nekaterih? No lahko bi spisali regex, kjer bi character class zamenjali s spiskom prepovedanih tagov, kar bi odprlo vrata vsem nepredvidenim. Lahko bi najprej matchali vse tage potem pa z zanko preverjali, kateri so dovoljeni in kateri ne ter delali zamenjave, kar pa je casovno potratno. Zato raje uporabimo asercije (assertion).

Asercije so v osnovi subpatterni, ki nekaj preverijo a tega ne matchajo, kar je sprva tezko razumljivo in po pravici povedano je to vedno nekaksen vudu, ki dela ali ne in se redkokdaj obnasa po izhodnih pricakovanjih. V osnovi poznamo dva tipa asercij; naprej in nazaj. Pisemo jih kot obicajne subpatterne, le da subpattern zacnemo z ?= za pozitivno asercijo ali ?! za negativno (podobno je ?<= in ? za nazaj asercije. Se najlazje si jih predstavljamo kot nekaksen if stavke ...

Tako bi lahko prejsnji problem resili nekako takole:

[koda]
$input = preg_replace( '#<([a-z]+)(?(.*?)', '$2', $input );

?>[/koda]

kar bi izbrisalo vse tage razen em, strong, b in i.

Podobno bi z naprej asercijo lahko v besedilu iskali vse janeze, ki niso novaki:

[koda]
preg_match_all( '#janez(?! novak)(p{L}+)#ui', $besedilo, $matches );

?>[/koda]

V $matches bi dobili vse janeze z njihovimi priimki in nihce od njih se ne bi pisal novak. Problem bi seveda nastal, ker se v slovenscini mosko ime sklanja skupaj s priimkom in bi zato morali upostevati samostalnik janez z vsemi koncnicami, v grobem nekaj takega:

[koda]
preg_match_all( '#janez(?:a|u|ov|e){0,1}(?! novak)(p{L}+)#iu', $besedilo, $matches );

?>[/koda]

Verjetno sem spustil marsikatero koncnico, ampak zelel sem prikazati se eno super lastnost subpatternov; namrec, ce ga zacnemo z ?: subpattern deluje isto kot ponavadi le, da je noncapturing in nam torej ne mece svojih matchev v array z rezultati.

Mimogrede, asercije lahko tudi druzimo skupaj, tako da lahko v besedilu iscemo npr. vsa stevila vecja od 100 a manjsa od 900 nekako takole:

[koda]
preg_match_all( '#(?
?>[/koda]

Ideja tu je, da najprej matchamo vse serije treh stevilk, ki sledijo nestevilom, potem se z asercijo najprej prepricamo, da ta stevila niso tipa 0xx, z naslednjo asercijo se prepricamo, da to niso stevila tipa 9xx (se pravi so vecja od 100 in manjsa od 900), s se naslednjo asercijo pa se prepricamo, da jim sledijo nestevilke. Pri vsem skupaj se je potrebno zavedati, da, ker so asercije v resnici dolge nic znakov, se vse zadnje tri asercije izvrsijo na istem mestu v stringu.

Za skoraj konec si poglejmo se pogojne subpatterne, ki nam omogocajo matchanje stringa pod nekim pogojem. Tako lahko preverjamo, ce je string zacetek "abecede" nekako takole:

[koda]
if ( preg_match( '#(?(^p{N})123|abc)#u', $string ) )

?>[/koda]

kar bi, ce je prvi znak stevilka, preverilo ce string matcha 123, drugace pa bi poskusilo z abc ... kar je seveda bolj neumen primer, ampak primere si je pac tezko izmisljevati.

Za konec pa se en bonboncek, sad dolgih dni truda in izboljsav (na zalost ne morem pokazati zadnje verzije, ta je predpredzadnja):
#((p{L}+(p{^L}+|^)){0,5}((?<=[^p{L}])Farting(?=[^p{L}])|(?<=[^p{L}])farting(?=[^p{L}])|(?<=[^p{L}])farts(?=[^p{L}])|(?<=[^p{L}])fart(?=[^p{L}]))((p{^L}+|$)p{L}+){0,5})|(^(([^p{L}]+|$)p{L}+){0,6})#u

To matcha okolico petih besed naprej in nazaj okoli razlicnih oblik besede 'fart' in sest besed na zacetku stringa ter, v prihodnjih verzijah, sest besed na koncu stringa.

Upam, da sem vam v tem clanku predstavil nekaj lastnosti in trikov v regexih, ki jih se niste vedeli, se vec o regexih pa si lahko preberete na php manualu, ce pa vam bo kdaj dolgcas se oglasite na mojem blogu.
Komentarji
#1 | lank na 07.08.2010 ob 07:48
buy gucci shoes Love your life, poor as it is. cheap gucci shoes You may perhaps have some pleasant, thrilling, cheap kamas glorious hours, even dofus kamas in a poorhouse. The kamas setting sun is reflected from the timberland shoes windows of the alms. Sq
Pošlji komentar
Za komentiranje se morate prijaviti.
Ocene
Za ocenjevanje se morate prijaviti.

Zelo dobro Zelo dobro 100% [2 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.03 sekunde 1,682,223 različnih obiskovalcev