regularis_kifejezesek
TRANSCRIPT
-
7/30/2019 Regularis_kifejezesek
1/6
Segtsg a RegEx hasznlathozA RegEx vagy RegExp a Regular Expression rvid formja. Magyarul taln a "szablyoskifejezs" lenne a megfelel fordts. Ez a lers azrt szletett, hogy elindtson a technikamegismersben, kornt sem tekinthet teljesnek, a cikk vgn tallhat URL-eken lehet
folytatni a barangolst a "szablyos kifejezsek" vilgban.
Mindig babons flelemmel nztem aRegEx mintira. Volt dolgom egykt nyelnvel, de ezvalami egszen bizarr dolog volt. Nem hinnm, hogy ltezik olyan tapasztalat aminek
birtokban felfedezhet a RegEx sajtos logikja, szintaktikja, viszont az opertorokelolvassa utn szinte arculcsap a felismers: "ennyi az egsz?" Legalbb is ez lenne a cikkclja :)
A RegEx lehetsget ad szablyok, azaz mintk egyszer lersra. Ezekkel a mintkkal aztnsok hasznos dolgot tehetnk. Kereshetnk rjuk egy stringben, vagy kicserlhetjkketvalamilyen szably szerint. Hasznlhatjuk adatellenrzsre vagy szerkezetek (pl. dtum)sztdarabolsra, rtelmezsre.
Essnk tl a ktelez analgin: a DOS-bl jlismertjoker karakterekis kifejezseket rnakle, amiknek fjlokat feleltetnk meg, vagy van egyezs, vagy nem. A ka*.doc ska???.doc kifejezsek kzl a kalap.doc mindkettnek, mg a kapa.doc csak az elsnekfelel meg.
Hogy mg egy kicsit rosszabb legyen, mieltt jobb lesz: DOS-os ka*.doc RegExmegfelelje: ka.*\.doc a ka???.doc peig nem ms, mint ka.{3}\.doc
RegEx opertorok
A DOS-os pldhoz hasonlan a mi mintink is konkrt karakterekbl (szavak, sztredkek),s specilis jelents opertorokbl plnek fel.
Karakter megfeleltets
. (pont)Brmilyen karakter: A b.ka kifejezsnek megfelel a bka s bika sz is.
[karakterek]A kapcsoszrjelek kztt felsorolt karakterek valamelyikvel megegyez karakter: Ab[a]ka kifejezsnek megfelel a bka s baka sz, a bika viszont nem. A -(minusz) jellel tartomnyt is megadhatunk. Pldul [0-9] megfelel brmely
szmjegynek vagy [a-zA-Z] brmely kis vagy nagybetnek.[^karakterek]
A kapcsoszrjelek kztt felsorolt karakterek egyikvel sem egyez karakter (azelz opertor tagadsa): A b[^]ka kifejezsnek nem megoldsa a bka. A bakas bika viszont igen.
Tbbszrzs
?
-
7/30/2019 Regularis_kifejezesek
2/6
A megelz minta 0 vagy 1 alkalommal fordul el: A borda.? kifejezs igaz aborda s a bordal szavakra is.
+A megelz minta 1 vagy tbb alkalommal fordul el: A bo.+ka kifejezsnekmegfelel a borka, a boka viszont nem.
*
A megelz minta 0 vagy tbb alkalommal fordul el: A bo.*ka kifejezsnek mrmegfelel a boka s borka is.
{m,n}Segtsgvel megadhat minimum s maximum vagy pontosan megadott szmelforduls - {3} pontosan 3 elforduls; {3,} legalbb 3 elforduls; {2,5} legalbb 2legfeljebb 5 elforduls; {,10} legfeljebb 10 elforduls. A d.{,5}ny igaz mindenesetben, ha legfeljebb 5 karaktert kell helyettesteni, pldul a dolmny esetn. Adiszkpatkny viszont mr nem akad fenn rajta.
Horgonyok
Az el
z
ekben nem szemlltettem, de a felsorolt kifejezsek akkor is igazak ha a vizsgltstring belsejben tallhatk meg. A b.ka igaz a bikaviadal mintra is.
^A minta eleje: Ezzel jelezhetjk, hogy a kifejezst a minta elejn keressk. A ^bkakifejezsnek megfelel a bkanyl minta, a kecskebka viszont nem.
$A minta vge: Az elz horgonyhoz hasonlan a minta vgt testesti meg. A k$mintnak megfelel minden erre vgzd sz (kerk, pk).
Termszetesen kombinlhatk is. A ^p.k$ kifejezs csak akkor igaz, ha az input pontosanegy hrombets sz. A legpiknsabb nem megoldsa, ahogy a pikns sem. A pkvagy pk
viszont j.
Logika
|Vagylagos egyezs: Kt lehetsg kz tve brmelyikkel val egyezs tallatot
produkl. Gyakorlati pldhoz picit elre kell ugorjunk, a norml (kerek) zrjelekre,jelen felhasznls viszont nem kvn klnsebb magyarzatot: ka(lap|bt)
( )Kifejezsek csoportostsa: Nem csak a vagylagos egyezs az egyetlen lehetsgesfelhazsnls. Egy csoportot ltrehozva ellthatjuk paramterrel pldul a
(hkusz)?pk segtsgvel a hkuszpks pkszavak is megtallhatk. Acsoportokra ksbb hivatkozhatunk is, ez csernl vagy stringek rtelmezsnl leszhasznos.
Escape-els
Ezek az opertorok lefednek nhny gyakran hasznlt karaktert is. Ha pldul egy pontkaraktert nem specilis rtelmben szeretnnk hazsnlni, hanem egy pontknt a C-bl, PHP-
-
7/30/2019 Regularis_kifejezesek
3/6
bl, Javascriptbl megszokott mdon \ (backslash) karakterrel tudjuk megfosztani specilisjelentstl.
sszetett pldk
Dtum feldolgozs[0-9]{4}[^0-9]*[0-9]{2}[^0-9]*[0-9]{2}
Hogy is olvasand a plda? [0-9]{4} ngy darab szmjegy (v); amelyet kvet [^0-9]*nulla vagy akr tbb NEM szmjegy karakter (esetleges elvlaszt); majd [0-9]{2} ktszmjegy (hnap); utna ismt [^0-9]* jhet elvlaszt; s vgl [0-9]{2} kt jabbszmjegy.
Ezzel mg csak flmunkt vgeztnk. Tudunk azonostani egy dtumot, de nem tudunkhivatkozni az egyes tagokra. A kerekzrjellel emeljk ki azokat a csoportokat amikszmunkra rdekes adatokat hordoznak.
([0-9]{4})[^0-9]*([0-9]{2})[^0-9]*([0-9]{2})
A hasznlt nyelvnek megfelel stlusban (ltalban egy tmbben) kapjuk vissza a megjelltcsoportok tartalmt a RegEx futtatsa utn. Pldul PHP-ben:
$datum = "2006. 07. 22."; ereg ('([0-9]{4})[^0-9]*([0-9]{2})[^0-9]*([0-9]{2})', $datum, $talalat); var_dump ($talalat);
Eredmnye a kvetkez:
array(4) { [0]=> string(12) "2006. 07. 22" [1]=> string(4) "2006" [2]=>string(2) "07" [3]=> string(2) "22" }
A tmb nulls sorszm rekeszbe kerl az egsz kifejezsnek megfelel minta (lthat, hogya vgs pont nincs benne, hiszen a keresett kifejezsnk vget r a napot jell ktszmjeggyel). Az egyes sorszmtl kezdve a tmbbe kerltek az ltalunk (kerekzrjellel)megjellt csoportok. A kiindulsi dtum lehetett volna "2006-07-22" vagy "20060722" is, akifejezs mindet megfejti.
Bizonyos dtumformtumok nem ptoljk ki ktszmjegyre az adatokat. Pdlul"2006/7/22". Ilyenkor az elvlasztk jelenlte a dnt. Az elvlasztk kztt mindig van egyvagy tbb szmjegy:
([0-9]{4})[^0-9]*([0-9]+)[^0-9]*([0-9]+)
Nzznk egy PHP pldt a csrre. A kvetkez fggvny a tetszlegesen elvlasztottdtumformtumot "-" jellel elvlasztottra konvertlja (ahogy pldul a MySQL szereti).
$datum = "2006. 7. 22."; $ujdaum = ereg_replace ('([0-9]{4})[^0-9]*([0-9]+)[^0-9]*([0-9]+)[^0-9]*', '\1-\2-\3', $datum); echo ($ujdaum); //eredmnye: 2006-7-22
-
7/30/2019 Regularis_kifejezesek
4/6
Itt megtoldottuk a mintt egy [^0-9]* kddal, hogy lenyeljk az esetleges elvlaszt jeleketa dtum vgrl. A \1 \2 \3 pedig referencik a zrjellel kiemelt csoportokra.
E-mail ellenrzs
^[0-9a-z\.-]+@([0-9a-z-]+\.)+[a-z]{2,4}$
Olvassuk el: ^ a minta elejn; egy vagy tbb alfanumerikus karakter, a pont s ktjel ismegengedett (A pont specilis karakter, egy backslash-sel jelljk, hogy nem szeretnnk,hogy most rtelmezze a RegEx motor. A minusz szintn specilis jelentssel br akapcsoszrjelek kztt. Az esetben a backslash-mdszer nhny rtelmeznek gondotokoz, ezrt hogy megfosszuk specilis jelentstl az utols kell legyen a zr kapcsoszrjeleltt.) Ezek utn egy @ (at) karakter kvetkezik; majd [0-9a-z-]+ egy vagy tbbalfanumerikus karakter; amit \. egy pont kvet. A mintt egy [a-z]{2,4} legalbb 2legfejlebb 4 betbl ll rsz (TLD) zrja $.
A kifejezs kzepn (kiemelt rsz) kpeznk egy csoportot, aminek engedlyeztk az
ismtl
dst. Ennek hatsra nem csak a "[email protected]" felel meg, hanem ugyangy a"[email protected]" is.
$email = "[email protected]"; $megfelel = eregi ('^[0-9a-z\.-]+@([0-9a-z-]+\.)+[a-z]{2,4}$', $email); echo ($megfelel); // azeredmny: 1
Most nem rtelmeznk, darabolunk, cserlnk, egyszeren csak ellenrizzk megfelel-e avizsglt minta a kifejezsnknek. Az eregi fggvny a kis s nagybetket nem klnbzteimeg, s neknk most erre van szksgnk.
Ugyanerre egyJavaScriptplda:
A plda forrsa:
function mailcheck() { var reg = /^[0-9a-z\.-]+@([0-9a-z-]+\.)+[a-z]{2,4}$/i; var s =document.getElementById('email').value; alert(reg.test(s)); }
A JavaScript a PERL kompatibilis szintaxist hasznlja (PCRE). Ez nem string. Idzjelekhelyett "/" hatrol karakterek kztt (itt ms hatrol nem hasznlhat) tallhat a minta,utna a flagekkel. Itt az i, azaz igonore-case flaget hasznljuk, azaz kis s nagybetknincsenek megklnbeztetve. A regtipusa teht nem String, hanemRegExp. Ennek
hazsnljuk a test() metdust az input ellen
rzsre.
URL formzott kirsa
Ttelezzk fel, hogy egy webcmet szeretnnk tetszets formban kirni: kiemelni adomainnevet s elvoltani az esetleges / jelet a vgrl. Mivel nem tudjuk, hogy konkrtanvan-e a vgn / (per) karakter szksgnk lesz egy feltteles kifejezsre. Az els kzenfekvmegolds:://([^/]+)(.*)(/$|$)
mailto:[email protected]:[email protected] -
7/30/2019 Regularis_kifejezesek
5/6
A :// a protokol vgt jelli, semmi specilis. A ([^/]+) kifejezs megtallja neknk ahostnevet, mivel az els / eltti sszes karaktert visszaadja. Az elrsi t tbbi tagja megfelela (.*) kifejezsnek. Ezutn pedig vagy egy / karakter majd a string vge kvetkezik, vagyazonnal a string vge. Logikusan hangzik, mgsem mkdik.
A problma az, hogy a (.*) elnyeli a zr / karaktert is. gy az utols csopotnak mr csak
string vge jel jut. A megolds:
://([^/]+)(.*?)(/$|$)
Ezt nevezik nem-kapzsi (non-greedy) keressnek. Ilyenkor a lehet legkevesebb karaktertvesz le magnak a kifejezs. Amint az utna kvetkez kifejezs (/$|$) egyezst produklnem eszik meg tbbet magnak.
A PHP eregfggvnyei nem ismerik ezt a keressi mdot. les helyzetekben mindenkppen agyorsabb PCRE fggvnycsaldot javaslom. A pldkban csak a picit bartsgosabbszintaktika miatt szerepel ereg. Lssuk most a pldtpreg(PCRE) hasznlatval:
$url = "http://domain.tld/dokumentumok/2006/"; preg_match('#://([^/]+)(.*?)(/$|$)#', $url, $talalat); var_dump ($talalat);
A legszembetnbb jdonsg az, hogy a PCRE fggvnyek hatrol karakterek (esetnkbenkettskereszt: #) kztt vrjk a kifejezst (errl ksbb bvebben). A hatrol karaktert mivlasztjuk meg. ltalban a per karakter hasznlatos, esetnkben viszont nem lenne clszer,mivel a mintnkban tbb helyen is szerepel. Ha a vlasztott hatrol karakter szerepel amintban, akkor a mr ismertetett mdon, egy backslash karakterrel kell escape-elni azt.
A futs eredmnye:
array(4) { [0]=> string(32) "://domain.tld/dokumentumok/2006/" [1]=>
string(10) "domain.tld" [2]=> string(18) "/dokumentumok/2006" [3]=>string(1) "/" }
Ahogy megszoktuk, a tmb nulls sorszm eleme az egsz tallatot tartalmazza, az ltalunkmegjellt csoportok az els indextl kezddnek: A protokoll utni els "/" karaker eltti rsz,azaz a hostnv; majd az URL tovbbi rsze; kivve a zr "/" karaktert, ami az utols csoport.
A darabok ismeretben kirhatjuk emberbart, style-olt URL-nket, ahol a hostnevettetszlegesen kiemelhetjk.
echo ('' . $talalat[1] . '' . $talalat[2] . '');
Bankszmlaszm ellenrzse
^[0-9]{8}([ -]?[0-9]{8}){1,2}$
A bankrendszer behatbb simerete nlkl felttelezem, hogy egy szmlaszm 16 vagy 24szmbl ll, s nyolcasval szoks t elvlasztani.
http://domain.tld/dokumentumok/2006/http://domain.tld/dokumentumok/2006/ -
7/30/2019 Regularis_kifejezesek
6/6
Olvassuk el: nyolc szmjegy (eddig semmi klns); majdjhet (krdjel, azaz 0 vagy 1darab elforduls) egy elvlaszt karakter (space vagy ktjel); ezutn ismt nyolc szmjegy.Az utols kt kifejezsbl ltrehozunk egy csoportot (kiemelt rsz - kerek zrjel), amibllegalbb egy (16 szmjegy szmlaszm) vagy legfeljebb kett (24 szmjegy szmlaszm)fordulhat el. A kifejezs a start "^" jellel kezddik s a vge "$" jelle fejezdik be, gy teljesegyezst viszglunk, nem elg, ha a minta csak tartalmazza a szmlaszmot (enlkl pldul a
"abc12345678-12345678" is megolds lenne).
Egy mkdJavaScriptplda:
s a forrs:
function szamlaCheck() { var reg = /^[0-9]{8}([ -]?[0-9]{8}){1,2}$/; var s =document.getElementById('szamlaszam').value; alert(reg.test(s)); }
Tovbbi tletek?Kimertettem minden eszembe jut pldt. Ha van egy (nem nagyon speciis) felhasznlsod,amire nem tallod a megoldst (vagy akr igen), s jl mutatna itt pldnak vrok mindentletet a kapcsolat oldalon.
Varga Bence 2007