PHP Centeri avaleht Skriptikogu Küsimuste-vastuste leht Teadete vaatamine ja saatmine Foorum - koht küsimiseks Otsingumootor Siit saad infot meie kohta

Kasutajanimi:  
  Parool: 
  Registreeri!   Unustasid salasõna?

 Skriptid (427) 

 Bannerisüsteemid
 E-kaardid
 E-maili saatmine
 E-poed
 Failihaldus
 Flash ja PHP
 Foorumid
 Jututoad
 Kalendrid
 Kalkulaatorid
 Kellad
 Klikilugejad
 Kommentaarid
 Külalisteraamatud
 Küsitlused
 Lehe turvamine
 Lingikogud
 Mängud
 Otsingusüsteemid
 Pildid ja PHP
 Shoutboxid
 Sisuhaldussüsteemid
 Statistika
 Suunamine
 Templeidisüsteemid
 Testid
 Uudised
 Uudistelistid
 Varia


 Otsing 

 

 Utiliidid 

 Kes on kus
 Kasutajate info
 Küsitlused
 PHP manuaal
 Õpetused
 Jututuba
 Lingikogu
 Lemmikskriptid


 Regulaaravaldised PHP-s
Autor: siku
Esmaspäev, 04. august 2003 16:06
Regulaaravaldised PHP-s

Sisukord
Sissejuhatus
POSIX-i regulaaraavaldised
Hulgatähised
Tähtede klassid
Tekstikübemed ehk aatomid
Regulaaravaldiste harud
Perliga ühilduvad regulaaravaldised
PCREs ja kurakaldkriipsudega tähed(backslashed characters)
Ankrud
Mudelite otsimine globaalselt
Mudelite muutjad
Kokkuvõtteks


Sissejuhatus
Kuna regulaaravaldistest on siin suhteliselt vähe juttu olnud, otsustasin teha nende kohta ühe pikema õpetuse.
Regulaaravaldised on võimas vahend teksti uurimiseks ja muutmiseks. Nende abil on võimalik leida tekstist teatud tüüpi sõnu, lauseid ja muid täheühendeid ning neid paindlikult lahti harutada ja teha asendusi. Nad on küll stringide töötlemiseks võimas vahend, kuid nad töötavad aeglasemalt kui tavalised stringide funktsioonid. Ärge nüüd järeldage, et peaksite hakkama
kasutama igal pool regulaaravaldisi, sest nad on võimsamad. Need on kasulikud siis, kui tavaliste stringi-funktsioonide võimalustest puudu tuleb. Selles õpetuses tulebki juttu just nendest regulaaravaldiste võimalustest, mida just igapäevases
veebiprogrammeerimises ette tuleb. Vaadake/lugege järgnev õpetus läbi ning järeldage ise, kus ja kuidas neid kasutada saab.

PHP toetab kahte tüüpi regulaaravaldisi. Sellel on olemas funktsioonid, mis toetavad nii PERL-i regulaarvaldisi kui ka POSIX-i regulaaravaldisi. Regulaaravaldiste kasutamist on võimalik märgata üsnagi mitmes kohas. Nende abil on võimalik valideerida e-maili aadresse, www-aadresse jne. Lisaks kasutatakse neid ka otsingusüsteemides. Näiteks mina olen küllaltki tihti otsinud oma arvutist .jpg-failie sellise regulaaravaldise abil: *.jpg . Õpetuses vaatamegi, kuidas regulaaravaldised töötavad ja mis funktsioonid on PHP-l nende kasutamiseks olemas.

POSIX-i regulaaravaldised
POSIX-i regulaaravaldiste funktsioonidega on võimalik otsida ja asendada muutujas keerulisi mudeleid või siis mustreid(ingl.k pattern).
Neid tuntakse PHP-s põhiliselt kui tavalisi regulaaravaldiste funktsioone.

Regulaaravaldis on sümbolite kombinatsioon, mis kattub tekstis oleva mudeliga. Et saada veelkord aimu, mis nad on ja
milleks neid vaja on, toome ära siin esimese lihtsa näite:

Näide1:
PHP kood:


<?
print 
ereg('hh''hehhee hahaa'$massiiv);
//väljastab '2' .
//ereg() käsk tagastab antud juhul leitud tähtede arvu.
print $massiiv[0]; //tagastab 'hh'
?>



Näide2:
Funktsiooni ereg() on võimalik kasutada ka tingimuslausetes:
PHP kood:


<?
$string="hehhee hahaa";
if(
ereg('hah',$string)) {
echo
"Sobivus leiti!";
} else {
echo
"Sobivust ei leitud!";
}
?>


Hulgatähised
* - null või enam instantse, näiteks 'a*' klapib sõnaga 'yxyxyxyx' ehk siis kõigega,
+ - üks või enam instantse, näiteks 'u+' klapib sõnaga 'huul' aga ei klapi sõnaga 'hihii',
? - null või üksainus juhtum, näiteks 'u?' klapib sõnaga 'huhh' aga ei klapi sõnaga 'huul',
{n} - n-arv instantse, näiteks 'u{2}' klapib sõnaga kuu aga mitte sõnaga 'uuuuu',
{n,} - vähemalt n-arv instantse, näiteks 'u{2,}' klapib sõnaga 'huul' aga mitte sõnaga 'huhh',
{,n} - kuni n-arv instantse, näiteks 'u{,2}' klapib sõnaga 'huul' aga mitte sõnaga 'uuul'.
{n1,n2] - vähemalt n1 arv instantse, aga mitte rohkem kui n2 arv instantse. Näiteks 'e{1,2}' klapib sõnaga 'teet', aga
mitte sõnaga 'teee'.

Toome väikese näite hulgatähiste kasutamisest:
Näiteks on meil andmebaasi tabelis artiklid, millel on oma spetsiifiline ID kood. On näiteks kahte tüüpi ID-sid:
- need, mis algavad tähekominatsioonida EE, ehk eestikeelsed artiklid,
- need, mis algava tähekombinatsiooniga EN, ehk inglisekeelsed artiklid.
ID koodi neli viimast numbrit tähistavad artikli ilmumise kuupäeva, sealhulgas viimased kaks on lühidalt aasta ja eelviimased 2 on kuu.
Näide 3:
PHP kood:


<?
$ID_kood="EE56741202";
$kuu="12"//kuu nr. lühidalt, ehk detsember.
$aasta="02"//aasta lühidalt, ehk 2002
if(ereg("E{2}.*".$kuu.$aasta."",$ID_kood,$leiud)) {
print 
"Artikkel on eestikeelne. Selle ID on: ".$leiud[0];
}
?>


Seletame nüüd koodi lahti:
Kõigepealt panime paika muutujad, millega hiljem hakkame tegutsema. Nendeks on $ID_kood, $kuu ja $aasta. Nüüd hakkasime kontrollima, mis keeles on käesolev artikkel. Selleks pidime tegema kindlaks, mis on ID koodi esimesed kaks tähte.
'E{2}' näitab, et kood peab sisaldama kõrvuti kahte E-d, seejärel järgneb '.*', mis tähistab suvalisi sümboleid ning lõpuks määrasime etteantud kombinatsiooni kuust ja aastast. Kui regulaaravaldis oli paika pandud, panime funktsiooni argumentideks veel stringi, millest
otsida ja massiivi, millesse leiud koguda.

Tähtede klassid
Siiamaani oleme kasutanud ainult ettemääratud tähti või kasutanud punkti (.) suvaliste tähtede jaoks. Tähtede klassid võimaldavad otsida ainult teatud sorti tähti ja nende kombinatsioone. Tähtede klassi defineerimiseks tuleb vajalikud tähed ümbritseda nurksulgudega([]). Pärast tähtede klassi defineerimist võib seda kohelda kui üksikut tähte. Näiteks '[ab]' klapib nii 'aaa'-ga, 'bbbb'-ga
kui ka 'abababab'-ga. Peale selle on võimalik määrata ka tähtede vahemikke, nii saabki otsida näiteks tähti vahemikus a-z kasutades klassi [a-z]. Pane tähele, et kui kasutad funktsiooni ereg(), siis sobivad nii suured kui ka väikesed tähed, funktsiooni eregi() puhul
on klappimine tõusutundlik, st. eristatakse suuri ja väikeseid tähti. Klassi [0-9] puhul otsitakse stringist ainult numbreid. Klasse saab ka kombineerida, näiteks klass [f-z8] sobib kõigi väiketähtedega f-st kuni z-ni ja number 5-ga. Lisaks võid nurksulgudesse lisada ^-märgi
([^a-z]), nii otsitakse ainult need sobivused, mis asuvad väikestest tähtedest a-z eemal.

Eelpool kirjeldatud skriptike pole eriti täiuslik, kuna seda ei saa kasutada pikemate muutujate(tekstide puhul). Näiteks leiab ta sobivuse ka siis, kui koodis pole EE-d, aga kuskil mujal on.

Lisaks tooks ära siin ka POSIX-i sisseehitatud tähtede klassid, mida saab kasutada ka Perli regulaaravaldistes:
[:alnum:] - alfabeetiline ja numbriline sümbol
[:alpha:] - alfabeetiline sümbol
[:blank:] - tühik ja tab
[:cntrl:] - kontrollsümbol
[:digit:] - numbrid
[:graph:] - ei ühtegi tühikut ega konrollsübolit
[:lower:] - väiksed tähed
[:print:] - nagu [:graph:], aga sisaldab ka tühiku sümbolit
[:punct:] - punktisümbolid
[:space:] - kõik tühikud, reavahetused jne
[:upper:] - suured tähed
[:xdigit:] - kuueteistkümnendsüsteemi arvud, näiteks 0-9a-fA-F

Näide 4: teksti seest ID koodi välja võtmine
PHP kood:


<?
$ID_kood="dfsdsf EE56741202, dsf fdsfsd";
$kuu="12"//kuu nr. lühidalt, ehk detsember.
$aasta="02"//aasta lühidalt, ehk 2002
if(ereg"E{2}[0-9]*".$kuu.$aasta."[^a-zA-Z0-9]"$ID_kood$leid)) {
print 
"ID kood on ".$leid[0];
}
?>


Seletame nüüd lahti:
E{2} tähistab kahte E-d sõna alguses, seejärel panime klassi [0-9], mis näitab, et EE-de taga on suvalised numbrid. Tärni abil sobitame kokku sinna ka kuupäeva ning kõige lõpuks tuli lisada ka '[^a-zA-Z0-9]', seda on vaja selleks, et ei tekiks segadust peale koodi olevate
tühikutega. Kui seda poleks, klapiks avaldis ainult siis, kui kood oleks muutuja lõpus. Kuid siiski pole see veel kuigi täiuslik. Sellest räägime hiljem.

Tekstikübemed ehk aatomid
Kübe ehk aatom on avaldis, mis asub sulgudes. Ta on nn. alammuster regulaaravaldises. Peale aatomi defineerimist võid sa seda kohelda nagu üksikut tähte või tähtede klassi ning klappida seda mustrit nii mitu korda kui ise tahad.

Näide 5:
PHP kood:


<?
$str="hakkahakkahakka";
if(
ereg("([ak]+h){2}"$str,$leid)) {
print
"Leiti: ".$leid[0];
}
?>


'[ak]+h' klapib 'akkah'-ga, aga '([ak]+h){2}' klapib 'akkahakkah'-ga. Esimene element massiivis $leid sisaldab tervet leitud kombinatsiooni.
Järgnev element massiivis sisaldab selle kombinatsiooni alamkombinatsioone.
Näiteks $leid[0]='akkahakkah', $leid[1]='akkah' jne.

Näide 6: lahkame IP-aadressi:
PHP kood:


<?
$ip="192.168.0.33";
if(
ereg("([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)",$ip,$massiiv)) {
foreach(
$massiiv as $ipelement) {
echo 
$ipelement."<br>\n";
}
}
//väljastab:
//192.168.0.33
//192
//168
//0
//33
?>


Siin määrasime aatomiks IP-aadressi elemendi, milles tohivad olla vaid numbrid '([0-9]+)' ja sellele järgneb punkt '\.'.

Regulaaravaldiste harud
Regulaaravaldisi saab ka kombineerida kasutades nö. harusid. Harude abil võimalik teostada klappimist või siis otsingut, millel on kaks või enam varianti. Näiteks kui sa teed kaheharulise avaldise, siis klapitakse nii esimese kui ka teise aru järgi jne. Harude eraldamisel avaldises kasutatakse püstkriipsu '|'. See annab regulaaravaldiste süntaksile juurde üsna palju uusi
võimalusi. Järgmises näites saategi näha, kuidas tunda tekstis ära näiteks domeene.

Näide 7: domeeni välja võtmine
PHP kood:


<?
$str="php.center.ee";
if(
ereg("\.ee|\.com|\.net",$str,$leitud)) {
echo
"Tegu on ".$leitud[0]." domeeniga";
//tegu on ee domeeniga
}
?>


Seletame nüüd koodi lahti. Nagu te ereg() funktsiooni esimesest argumendist välja lugesite, on seal selline avaldis: '\.ee|\.com|\.net'.
Kui see nüüd laiali lammutada, saame sealt kolm haru: '\.ee','\.com','\.net'. Kaldkriips punkti ees on selleks, et punkt tegelikult ise on ka ju üks regulaaravaldiste süntaksi osa, sellel nn. escape-miseks või siis eraldamiseks on vajalik kaldkriips(samamoodi tee kõigi sümbolitega,
mis kuuluvad regulaaravaldiste süntaksisse). Siiamaani kõik üsna lihtne?

Peale selle, et sa saad määratleda mustreid, mida sa stringist otsid, saad ka määrata, kust sa seda sealt täpselt otsid. Selleks, et kontrollida, kas sõna asub stringi alguses, kasutatakse '^'-märki(Alt Gr+Ä). Näiteks '^p' klapib 'php'-ga, kuid mitte näiteks 'hapu'-ga. Aga on võimalik otsida ka stringi lõpust. Selleks kasutatakse dollari($) märki.
Selleks kirjutakse avaldise või tähe taha dollarimärk. Näiteks 'a$' klapib sõnaga 'kala', aga mitte sõnaga 'kaal'. ^ ja $-märgid on nn. regulaaravaldiste ankrud.
Kui tee veel vahepeal magama pole jäänud, siis võiks täiustada meie eespool tehtud ID koodi skripti. Nüüd oleme juurde õppinud piisavalt vahendeid,
et teha see natuke töö- ja ka lollikindlamaks.
Eespool õpetatud vahendite abil saame koodi, mis võtab ID koodi stringist ilusti välja:

Näide 8: teatud omadusega sõna välja võtmine stringist
PHP kood:


<?
$str "raamatu kood on on see ikka õige? ma sad sadsajd EE56741202, sajdsaldj sadsaddsafdsf dsfsdfds";
$kuu="12";
$aasta="02";
if(
ereg"(^|[a-zA-Z0-9])(E{1,4}[0-9]*".$kuu.$aasta.")([^a-zA-Z0-9])",$str,$m)) {
print 
$m[2];
}
?>



'(^|[a-zA-Z0-9])' - see on siis esimene alammuster, mis uurib stringi algusest, seejärel uurime, kas leidub ka meile vajalik sõna(ID kood) mustri '(E{1,4}[0-9]*".$kuu.$aasta.")'
abil. Nüüd on vaja vaid otsing lõpetada, sest peale meile vajalikku sõna võib veel sümboleid olla. Selle teeme kindlaks mustri '([^a-zA-Z0-9])' abil.
Saimegi kokku kolm alammustrit: stringi algus, otsitav ja see, mis võib järgneda otsitavale.

Tutvustaksin nüüd natuke funktsioone, mida saab PHP-s regulaaravaldistega kasutada.
ereg_replace() - see on sarnane funktsioonile ereg() ja eregi(), kuid sellega saab asendada leitud mustreid vajaliku stringi või sõnaga.
Samamoodi toimib ka funktsioon eregi_replace(), kuid see on tõusutundlik.

Näide 9: funktsioon ereg_replace()
PHP kood:


<?
$str "raamatu kood on EE34741202, on see ikka õige? ma sad sadsajd sajdsaldj sadsaddsafdsf dsfsdfds";
$kuu="12";
$aasta="02";
if(
ereg"(^|[a-zA-Z0-9])(E{1,4}[0-9]*".$kuu.$aasta.")([^a-zA-Z0-9])",$str,$m)) {
$muudetud_str=ereg_replace("(^|[a-zA-Z0- 9])(E{1,4}[0-9]*".$kuu.$aasta.")([^a-zA- Z0-9])","<strong>".$m[2]."</strong>",$str);
print 
$muudetud_str;
}
?>



Stringi tükeldamiseks massiiviks regulaaravaldiste abil on olemas funktsioonid split() ja spliti(), nende täpsema kasutuse kohta võite uurida näiteid PHP Manuaalist.

Lisaks üks funktsioonike, mis sai tehtud kunagi e-maili korrektsuse kontrollimiseks:
PHP kood:


<?
# funktsioon e-maili korrektsuse kontrollimiseks
function on_oige_email($email) {
if(
eregi("^[a-z0-9]+([-_\.]?[a-z0-9])+@[ a-z0-9]+([-_\.]?[a-z0-9])+\.[a-z]{2,4}",$email)) {
return 
true//kui on õige, väljastane true
} else {
return 
false//kui ei klapi, siis väljastame false
}
}
/* kui nüüd avaldis tükkideks lammutada, saame:
^[a-z0-9] - stringi algus
+(plussmärk) selleks, et otsa liita
([-_\.]?[a-z0-9]) - juhul kui aadress peaks sisaldama punkti, sidekriipsu, alakriipsu ja selle
järgnevat sõna, ei tohiks neid olla üle ühe
+@ - ät märk peab pindlasti olema
[a-z0-9] - peale ät märki järgnev serveri nimi või aadress
([-_\.]?[a-z0-9]) - pluss punktiga eraldatud lisad nimes
\.[a-z]{2,4} - ning lõpuks domeen, milles peab olema vähemalt kaks tähte ja neid ei tohiks olla üle nelja
*/
$mail="php@center.ee";
if(
on_oige_email($mail)) {
echo
"Õige";
} else {
echo
"Vale";
}
?>



PERLiga ühildivad regulaaravaldised(PCREs - PERL COMPATIBLE REGULAR EXPRESSIONS)
Neile, kes on rohkem tegelenud programmeerimisega Perlis, on heaks 'vidinaks' PHP-s ka Perli regulaaravaldiste toetus.
PCREs-i süntaks on funktsionaalsem ja võimsam kui see, mida me just eespool vaatlesime.
Enne kui asume uurima Perli regulaaravaldisi, tahaksin ära tuua näite funktsiooniga preg_match($muster,$allikas,$massiiv), mis on oma olemuselt sama,
mis ereg() või eregi(), aga erinevuseks on asjaolu, et regulaaravaldis tuleb selles panna kaldkriipsude '/' vahele, Ärge ajage segi seda
tagurpidi kaldkriipsuga ehk backslash-ga.

Näide 10: preg_match() ja Perli regulaaravaldise kasutamine
PHP kood:


<?
//otsime sõna, mis algab m-ga ja lõpeb a-ga
$str="see on muna, mille munes kana";
if(
preg_match("/m..a/",$str,$m)) {
echo 
"leiti:".$m[0];
//leiti: muna
}
?>



Kui lisada näiteks punktile tärn('/m.*a'):
Näide 11: preg_match() ja Perli regulaaravaldise kasutamine
PHP kood:


<?
$str="seda on muna, mille munes kana";
if(
preg_match("/s.*a/",$str,$m)) {
echo 
"leiti:".$m[0];
//leiti: seda on muna, mille munes kana
}
?>


's.*a' tähendab, et klapib mudel, millel on peale s-i ja enne a-d võimalikult palju tähti või muid sümboleid.
Kui panna veel peale tärni küsimärk('s.*?a'), tähendab see seda, et otsitakse mudelit, millel oleks s-i ja a-vahel võimalikult vähe tähti.

PCREs ja kurakaldkriipsudega tähed(backslashed characters)
Nii nagu eraldad sa teatud sümboleid kurakaldkriipsuga stringis(\n,\t,\r jne), eraldatakse ka teatud sümboleid Perli
regulaaravaldistes. Perlis on olemas mõningad sümbolid, mis ühilduva teatud teksti iseloomu tüüpidega:
\d - ükskõik, milline number
\D - kõik peale numbrite
\s - igat tüüpi tühikud
\S - kõik peale tühikute
\w - igasugune sõna täht, sh. alakriips
\W - kõik peale sõna tähtede, sh. alakriips

Nende sümbolite abil saame vältida (pikki) tähtede klasse, millest rääkisime eespool ning kirjutada lihtsama ja lühema koodi.
Näiteks
Näide 12:
PHP kood:


$tekst="muna";
ereg("m[a-zA-Z0-0_]a",$tekst,$massiiv);
//on sama mis
preg_match("/m\w+a/",$tekst,$massiiv);



Ankrud
Perli regulaaravaldised(PCREs) toetavad ka ankruid, millega saab määrata positsiooni stringis ilma, et peaks klappima
mõne tähega stringis.
Kurakaldkriips tuleks ette panna järgmistele tähtedele:
\A - stringi algus
\b - sõna piir, lõpp
\B - mitte sõna lõpp
\Z - stringi lõpp, klapib viimase reavahetusega või stringi lõpuga
\z - stringi lõpp, klapib stringi täieliku lõpuga
Tooksin siinkohal ka pisikese näite nende kasutusest:
Näide 13:
PHP kood:


<?
$string="tere, mina olen üks friik. Minu emakeeleks on PHP.";
if(
preg_match("/\.\z/",$string,$m)){
echo 
"Tubli poiss! Viitsid ikka lause lõppu punkti panna";
}
?>


Seda lihtsat näidet ei ole vist vaja enam lahti seletada kui olete ikka algusest peale jälginud.

Mudelite otsimine globaalselt
Kui me kasutame teksti läbikammimiseks POSIX-i funktsioone, siis otsitakse nii kaua, kuni leitakse esimene juhtum. Peale seda enam edasi ei otsita. Selleks, et kammida läbi kogu tekst ja leitud tulemused massiivi jäädvustada, peaksime kasutama funktsiooni preg_match_all(). Selle funktsiooni abil on võimalik otsida strigist üles iga mudel ühe funktsiooni kutsumisega.
Näide 14: preg_match_all()
PHP kood:


<?
$str="Poes on müügil porgandeid, parukaid, pulkasid, pardleid ja puid.";
if(
preg_match_all("/\bp\w+d\b/",$str,$massiiv)) {
for(
$i=0;$i<count($massiiv);$i++) {
for(
$j=0;$j<count($massiiv[$i]);$j++) {
print 
"\$massiiv[$i][$j]: ".$massiiv[$i][$j]."<br>\n";
}
}
}
//väljastatakse:
//$massiiv[0][0]: porgandeid
//$massiiv[0][1]: parukaid
//$massiiv[0][2]: pulkasid
//$massiiv[0][3]: pardleid
//$massiiv[0][4]: puid
?>


Esimeseks elemendiks massiivis "$massiiv" on veel üks massiiv muutujatega. Massiiv sisaldab igat sõna, mis algab 'p'-ga ja
lõpeb 'd'-ga.
preg_match_all() tekitab multidimensionaalse massiivi hoidmaks leitud tulemusi alammudelites. Esimene massiivi element sisaldab igat sobivust regulaaravaldisest. Iga lisaelement sisaldab sobivusi, mis vastab igale aatomile. Järgmise näite abil saate endale pildi silmade ette, mismoodi asi töötab. for tsükleid pole vaja vast seletama hakata. Nende abil saamegi välja lugeda kõik peamassiivi elemendid ehk massiivid ning nende seest alammassiivide elemendid.
Näide 15: preg_match_all()
PHP kood:


<?
$str="30.07.2003, 31.07.2003, 01.08.2003";
if(
preg_match_all("/(\d+)\.(\d+)\.(\d+)/"$str$massiiv)) {
for(
$i=0;$i<count($massiiv);$i++) {
for(
$j=0;$j<count($massiiv[$i]);$j++) {
print 
"\$massiiv[$i][$j]: ".$massiiv[$i][$j]."<br>\n";
}
}
}
//väljastatakse
/*
$massiiv[0][0]: 30.07.2003
$massiiv[0][1]: 31.07.2003
$massiiv[0][2]: 01.08.2003
$massiiv[1][0]: 30
$massiiv[1][1]: 31
$massiiv[1][2]: 01
$massiiv[2][0]: 07
$massiiv[2][1]: 07
$massiiv[2][2]: 08
$massiiv[3][0]: 2003
$massiiv[3][1]: 2003
$massiiv[3][2]: 2003
jne...
*/
?>



Räägiksin ka natuke asendamistest Perli regulaaravaldistega. Kindlasti on teil meeles veel POSIX-i osast sellised funktsioonid nagu ereg_replace() ja eregi_replace(). Nii nagu on seal olemas asendusfunktsioonid, on need olemas ka siin.
preg_replace() käitub samamoodi nagu ereg_replace() ja eregi_replace, ainult siin on juba lisaks ka Perli regulaaravaldiste ühilduvus.
Selle funktsiooni kohustuslikud argumendid on mudel, asendus ja allikas.
Toome ära siin lihtsa näite selle funktsiooni kasutusest. Kindlasti olete seisnud või siis kunagi äkki seisate sellise probleemi ees nagu kuupäeva formaadi muutmine näiteks mõne muu riigi omast eestipäraseks. Timestamp-i puhul poleks probleemi, aga kui näiteks on kuupäev teile
esitatud kujul '06.24.2002'. Nagu näete, oleks omavahel vaja kohad ära vahetada '06'-l ja '24'-l.
Näide 16: preg_replace()
PHP kood:


<?
$kp="06.24.2002";
$formaadis_kp=preg_replace("|\b(\d+)\.(\d+)\.(\d+)\b|""\\2.\\1.\\3"$kp);
print 
$formaadis_kp;
//väljastatakse 24.06.2002
?>


Märkasite, et me kasutasime siin eraldajana püstkriipsu. See säästab meid eraldamast kaldkriipse mudelist, millega tahame klappida. Allika muutuja asemel saad sa edasi anda massiivi muutujatega preg_match()-le ja see muudab igat stringi. Sel juhul tagastatakse ka massiiv asendatud muutujatega. Samamoodi saab talle ette sööta ka massiivi, milles asuvad asendused(muutujad ja/või regulaaravaldised).
Allika muutujale rakendatakse iga massiivis asuv regulaaravaldis ning sellele omakorda rakendatakse ka teisest massiivist korrespondeeruv
element. Vaadake järgmist näidet:
Näide 17: massiividega asendamine preg_replace()-s
PHP kood:


<?
$str "06.24.2001, 07.31.2003 Copyright 1996";
$avaldismudelid array"|\b(\d+)\.(\d+)\.(\d+)\b|""/([Cc]opyright) (\d+)/" );
$asendusmudelid array"\\2.\\1.\\3""\\1 ".date(Y)."" );
$str preg_replace($avaldismudelid$asendusmudelid$str);
print 
"$str<br>";
// Väljastab "24.06.2001, 31.07.2003 Copyright 2003"
?>


Seletame koodi lahti. Kõigepealt koostame kaks massiivi, esimeses asuvad otsitavad mudelid ja teises asuvad mudelid, millega me asendame leitud mudelid. Esimene element massiivist '$avaldismudelid' korrespondeerub massiivi '$asendumudelid' esimesele elemendile jne.
Kui asendusmuutujatege/mudelitega massiiv on väiksem kui avaldismudelite massiiv, toimub asendamine ikkagi korrepondeeruvalt, kuid siin on asjaolu, et kui ei leita teisest massiivist korrespondeeruvat elementi, asendatakse see tühja muutujaga. Kui sa paned
avaldismudeliteks massiivi ja asenduseks tavalise muutuja, asendatakse iga massiivi element selle sama muutujaga.

Mudelite muutjad
Perliga ühilduvad regulaaravaldised lubavad sul kasutada teatud sümboleid, mis muudavad regulaaravaldise käitumist selle rakendamisel.
Mudeli muutja on täht, mis tuleks panna peale viimast eralduskaldkriipsu sinu regulaaravaldises. See täiustab/muudab seejärel terve regulaaravaldise käitumist.
Tooksin siinkohal ära nimekirja mudelite muutjatest, mida kasutab PCRE.
/i - tõusutundlik
/e - asendusmuutujat koheldakse preg_replace()-s nagu PHP koodi
/m - $ ja ^ klapitakse käesoleva rea alguses ja lõpus
/s - klapitakse reavahetused(tavaliselt pole need klapitavad)
/x - loetavuse abistamisesk ei loeta tühikuid, mis asuvad väljaspool tähtede klasse. Tühiku klappimisek kasuta \s, \t, või \
/A - klapib mudeli ainult stringi alguses(Perlis seda pole)
/E - klapib mudeli ainult stringi lõpus(Perlis seda pole)
/U - teeb regulaaravaldise mitteaplaks, minimaalne lubatud klappimiste arv(Perlis seda pole)
Seal, kus nad üksteisele vastu ei räägi(pole vastupidised), võid sa kombineerida ka mudeli muutjaid. Näiteks võid sa kasutada
muutjat 'x', et oleks lihtsam lugeda, samas aga sõltumata tähtede suurusest. Toome siin ära kohe lihtsa näite:
Näide 18: mudeli muutja kasutamine
PHP kood:


<?
$str="tere"//võib olla ka TERE
if(preg_match("/t\S*e/ix",$str,$massiiv)) {
echo 
"Leiti: ".$massiiv[0]; //Leiti: tere
}
//kui $str oleks "t e r e" või "T E R E", siis ei leiaks
?>
[PHP]
'm' muutja on kasulik siis, kui sa tahad klappida ankurdatud mudelit tekstis mitmel erineval real. Ankru mudelid '^' ja '$' klapivad vaikimisi algust ja lõppu tervel stringil. Järgnev koodijupp kasutab 'm' muutjat selleks, et muuta '$'-i käitumist.
[B]Näide 19: mudeli muutja kasutamine(ix)[/B]
[PHP]
<?
$str
="nimi: siku\namet: programmeerija\nvanus: 19\n";
preg_match_all("/^\w+:\s+(.*)$/m",$str$massiiv);
foreach (
$massiiv[0] as $element)
print 
$element."<br>";
/*
nimi: siku
amet: programmeerija
vanus: 19
*/
foreach ($massiiv[1] as $element)
print 
$element."<br>";
/*
siku
programmeerija
19
*/
?>


Me koostasime regulaaravaldise, mis klapib kõigi sõnasümbolitega, mis järgnevad koolonile ja suvaline arv tühikusümboleid.
Seejärel me klappisime suvalise arvu sümboleid, mis järgnesid stringi lõpu ankrule('$'). 'm'-i tõttu käitub nüüd '$' hoopis nüüd
realõpu tähisena.

's' muutja on kasulik siis, kui sa tahad klappida sümboleid punkti(.) abil üle mitme rea. Näiteks on sul mitmerealine tekst ja sa soovid võtta sellest esimese ja viimase sõna.
Toome siin ära kohe näite:
Näide 20: mudeli muutja kasutamine(s)
PHP kood:


<?
$str "alustame selle rea\nja siis oleme veel teisel real\nning lõpuks olemegi lõpus\n";
preg_match("/^(\w+).*?(\w+)$/s",$str,$massiiv);
print 
"$massiiv[1] $massiiv[2]<br>";
//väljastatakse: "alustame lõpus"
?>



'.' ei loe ilma 's'-ta tekstist välja reavahetuse sümboleid, kui panna see avaldise taha, siis eristab '.' reavahetused ning lugemine õnnestub.
Toome siin ka väikese näite sellest, kus 'e' saab kasulik olla. Oletame, et meil on tekst, milles on vaja muuta teatud tüüpi sõnad paksuks.
Võtame meie siin luubi alla aastaarvud.
Näide 21: PHP koodi arvestamine mudelite asendamisel
PHP kood:


<?
//funktsioon, mis teeb teksti rasvaseks
//argumentideks muudetav tekst ja stiil
function tekstRasvaseks($tekst,$stiil="")
{
return 
"<strong".($stiil!==""?" style=\"".$stiil."\"":"").">".$tekst."</strong>";
}
//teeme mingi suvalise stringi, milles oleksid aastaarvud
$str="praegu on 2 aasta ".date(Y).", varsti aga on ".(date(Y)+1).", mul on 2100 krooni";
//echo'me ehk väljastame asendatud muudetud stringi
echo preg_replace("/([0-2][0][0-9][0-9])/e","tekstRasvaseks(\\1,'color: red')",$str);
//väljastatakse "praegu on 2 aasta <strong style="color: red">2003</strong>, varsti aga on <strong style="color: red">2004</strong>, mul on 2600 krooni"
?>


Me otsime stringist üles kõik neljakohalised numbrid(aastaarvud) ja teeme need punaseks boldiks. Maksimum arv, mis veel aastarvus arvestatakse ja punasena
näidatakse on 2099. Proovige seda skripti ja mõelge, kus teie saaksite kasutada mudelite muutjaid!

Kokkuvõtteks
Regulaaravaldised on tegelikult suhteliselt mahukas teema. Selles õpetuses jõudsime läbi vaid pinnapealse osa sellest, mida nendega teha saab. Aga siiski peaksid sa nüüd oskama kasutada regulaaravaldiste funktsioone, et otsida ja asendada keerulisi tekstimudeleid. Selles õpetuses tõin teieni 21 näidet regulaaravaldiste kasutamise kohta, hulgatähised, sisseehitatud klassid, teatud iseloomuga sümbolid regulaaravaldistes ning ka mudelite muutjad. Regulaaravaldiste abil on võimalik lahendada väga palju keerukaid probleeme, mida esineb just veebiprogrammeerimises. Loodetavasti on sellest õpetusest kasu! Edu veebiehitamisel !

NB: Kõiki näiteid on enne siia õpetusse panemist edukalt testitud. Kui tekib seoses selle õpetusega küsimusi, siis palun esitage need foorumis.

Autor: Sigmar Muuga
(c) 2003



Avaleht   -    Skriptikogu   -    Teated   -    Foorum   -    Reklaam   -    Tagasiside   -    Kasutamise reeglid

© Copyright 2002-2019 PHP Center. Kõik õigused reserveeritud.