regularis_kifejezesek

Upload: feherl2

Post on 14-Apr-2018

213 views

Category:

Documents


0 download

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