OPPITUNTI 18 Säännöllisten lausekkeiden käyttäminen



Samankaltaiset tiedostot
Ohjelmoinnin perusteet Y Python

3.1 Mitä tarkoittaan heredoc? Milloin sitä kannattaa käyttää? Kirjoita esimerkki sen käyttämisestä.

Ohjelmoinnin peruskurssi Y1

6. Funktiot 85. Kuinka funktioita määritellään ja kutsutaan. Kuinka funktioille viedään arvoja ja niistä palautetaan arvoja

OPPITUNTI15 Päivämäärien käsittely

Ohjelmoinnin perusteet Y Python

Johdatus Ohjelmointiin

OPPITUNTI 3 Ensimmäinen skripti

Datatähti 2019 alku. task type time limit memory limit. A Kolikot standard 1.00 s 512 MB. B Leimasin standard 1.00 s 512 MB

PERL. TIE Principles of Programming Languages. Ryhmä 4: Joonas Lång & Jasmin Laitamäki

Korpusten käsittely clt131, P Luento 5

MITÄ JAVASCRIPT ON?...3

Luento 5. Timo Savola. 28. huhtikuuta 2006

OPPITUNTI 17 Merkkijonoilla työskentely

Tehtävä 2: Loppuosataulukko

Korpusten käsittely clt131, P Luento 3

CLT131 Korpusten käsittely

PERUSLASKUJA. Kirjoita muuten sama, mutta ota KAKSI välilyöntiä (SEURAA ALUEMERKINTÄÄ) 4:n jälkeen 3/4 +5^2

Ohjelmoinnin perusteet Y Python

KESKI-SUOMEN MAAKUNNAN JA LÄHIKUNTIEN LUKIOIDEN TIETOTEKNIIKAN II KILPAILU

Ohjelmoinnin perusteet Y Python

Luonnolliset vs. muodolliset kielet

Ohjelmoinnin perusteet Y Python

Zeon PDF Driver Trial

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

Tehtävä 2: Säännölliset lausekkeet

PERUSLASKUJA. Kirjoita muuten sama, mutta ota välilyönti 4:n jälkeen 3/4 +5^2

7. Taulukot 105. Kuinka taulukoiden tietoa käsitellään ja lajitellaan

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

Pythonin Kertaus. Cse-a1130. Tietotekniikka Sovelluksissa. Versio 0.01b

Merkkijono määritellään kuten muutkin taulukot, mutta tilaa on varattava yksi ylimääräinen paikka lopetusmerkille:

Osoitin ja viittaus C++:ssa

Harjoitustyö: virtuaalikone

OPPITUNTI 5 Ohjelman kulku

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

Python-ohjelmointi Harjoitus 5

Hyvän salasanan tunnusmerkit Hyökkääjästä salasanan pitää näyttää satunnaiselta merkkijonolta. Hyvän salasanan luominen: Luo mahdollisimman pitkä

Harjoitus 2 (viikko 45)

Merkkijonon tutkiminen matches-metodilla

Ohjelmoinnin perusteet Y Python

VeRan laboratoriotietojen siirtoformaatti

Matematiikan tukikurssi

ITKP102 Ohjelmointi 1 (6 op)

Tietorakenteet, laskuharjoitus 7, ratkaisuja

815338A Ohjelmointikielten periaatteet Harjoitus 7 Vastaukset

OPPITUNTI 16 Tiedon käsittely

SELECT-lauseen perusmuoto

Vektorit. Vektorin luominen Vektorin tuominen näyttöön Vektorin koon ja alkioiden muokkaaminen Vektorin poistaminen...

Osa. Listaus 2.1. HELLO.CPP esittelee C++ -ohjelman osat. 14: #include <iostream.h> 15: 16: int main() 17: {

Se mistä tilasta aloitetaan, merkitään tyhjästä tulevalla nuolella. Yllä olevassa esimerkissä aloitustila on A.

Rakenteiset tietotyypit Moniulotteiset taulukot

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

ITKP102 Ohjelmointi 1 (6 op)

kertaa samat järjestykseen lukkarissa.

Matematiikan tukikurssi, kurssikerta 3

Ohjelmoinnin perusteet Y Python

11. oppitunti III. Viittaukset. Osa. Mikä on viittaus?

Hahmon etsiminen syotteesta (johdatteleva esimerkki)

5.2 Ensimmäisen asteen yhtälö

Tietorakenteet ja algoritmit

Algoritmit 2. Luento 9 Ti Timo Männikkö

KESKUSTANUORTEN NETTISIVUT- OHJEITA PIIRIYLLÄPITÄJÄLLE 1. KIRJAUTUMINEN

8. Oliot 123. Kuinka luokkia luodaan ja olioita saadaan aikaan. Kuinka luodaan ja käsitellään ominaisuuksia ja metodeja

Taulukot. Jukka Harju, Jukka Juslin

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

1. (a) Seuraava algoritmi tutkii, onko jokin luku taulukossa monta kertaa:

ASCII-taidetta. Intro: Python

Kerta 2. Kerta 2 Kerta 3 Kerta 4 Kerta Toteuta Pythonilla seuraava ohjelma:

VERKKOSOVELLUSTEN OHJELMOINTI, JOHDATUS PHP:HEN

PHP tehtävä 3 Atte Pekarinen TIKT13A

KAAVAT. Sisällysluettelo

Algoritmit 2. Luento 13 Ti Timo Männikkö

TAMPEREEN TEKNILLINEN YLIOPISTO

Java-kielen perusteita

Datatähti 2019 loppu

Toinen harjoitustyö. ASCII-grafiikkaa 2017

Algoritmit. Ohjelman tekemisen hahmottamisessa käytetään

Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes)

Erittäin nopea tapa saada kehitysympäristö php:lle pystyyn Voidaan asentaa muistitikulle

Talousmatematiikan perusteet, L3 Prosentti, yhtälöt Aiheet

Ctl160 Tekstikorpusten tietojenkäsittely p.1/28

3 Suorat ja tasot. 3.1 Suora. Tässä luvussa käsitellään avaruuksien R 2 ja R 3 suoria ja tasoja vektoreiden näkökulmasta.

Lausekielinen ohjelmointi II Ensimmäinen harjoitustyö

Wordpress- ohje nettisivujen laadintaan

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti

5.6. C-kielen perusteet, osa 6/8, Taulukko , pva, kuvat jma

Käänteismatriisin. Aiheet. Käänteismatriisin ominaisuuksia. Rivioperaatiot matriisitulona. Matriisin kääntäminen rivioperaatioiden avulla

Tiedostonhallinta. Yleistä

Asiakirjojen vertailu-kurssi

Matematiikan tukikurssi

Tietotekniikan valintakoe

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5)

Algoritmit 2. Luento 6 To Timo Männikkö

PERUSLASKUJA. Kirjoita muuten sama, mutta ota välilyönti 4:n jälkeen 3/4 +5^2 3

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti

Suvi Junes/Pauliina Munter Tietohallinto/Opetusteknologiapalvelut 2014

Transkriptio:

18. Säännöllisten lausekkeiden käyttäminen 319 OPPITUNTI 18 Säännöllisten lausekkeiden käyttäminen Säännölliset lausekkeet ovat tehokas keino tutkia ja muokata tekstiä. Ne mahdollistavat kuvioiden etsimisen merkkijonosta ja osaavat erottaa vastaavat kohdat joustavasti ja tarkasti. Ole kuitenkin varovainen, koska tehokkuutensa vuoksi ne ovat samalla myös hitaampia kuin tavalliset merkkijonofunktiot, joita tutkimme luvussa 17, "Merkkijonojen käsittely". Käytä siksi merkkijonofunktioita aina, kun nopeus ja tehokkuus ovat elintärkeitä. PHP tukee kahta säännöllisten lausekkeiden joukkoa. Sillä on joukko funktioita, jotka emuloivat PERL-kielen säännöllisiä lausekkeita ja funktiojoukko, joka tukee rajallisemmin POSIX-järjestelmän mukaisia säännöllisiä lausekkeita. Tutkimme tässä luvussa molempia lausekkeita. Tämän tunnin aiheita ovat seuraavat: Kuinka hakea kuvioita merkkijonoista säännöllisten lausekkeiden avulla Säännöllisten lausekkeiden syntaksin perusteet Kuinka korvata merkkijonojen teksti säännöllisten lausekkeiden avulla Kuinka työskennellä tehokkaammilla, PERL-yhteensopivilla säännöllisillä lausekkeilla

320 18. Säännöllisten lausekkeiden käyttäminen POSIXin mukaiset säännölliset lausekkeet POSIXin säännöllisten lausekkeiden funktiot mahdollistavat monimutkaistenkin kuvioiden hakemisen merkkijonoista ja kuvioiden korvaamisen. Niitä kutsutaan yleisesti vain säännöllisten lausekkeiden funktioiksi, mutta kutsumme niitä tässä kirjassa POSIXin säännöllisiksi lausekkeiksi erottaaksemme ne samanlaisista, mutta tehokkaammista PERL-yhteensopivista säännöllisistä lausekkeista; lisäksi nämä säännölliset lausekkeet ovat POSIXin laajennettujen säännöllisten lausekkeiden määrittelyn mukaisia. Säännöllinen lauseke on joukko symboleja, jotka vastaavat tekstissä olevaa merkkikuviota. Näiden lausekkeiden käyttämisen oppiminen on paljon enemmän kuin PHP:n säännöllisten lausekkeiden funktioiden argumenttien ja palautustyyppien oppiminen. Aloitamme funktioilla ja käytämme niitä esitelläksemme säännöllisten lausekkeiden syntaksin. Kuvioiden vastineiden hakeminen ereg()-funktiolla Funktio ereg() ottaa argumentikseen merkkijonon, joka edustaa kuviota sekä merkkijonon, joka edustaa tutkittavaa tekstiä ja vielä taulukkomuuttujan, johon haun tulokset laitetaan. Funktio palauttaa kokonaisluvun, joka edustaa vastanneiden merkkien määrää, jos kuvio löytyi merkkijonosta, tai muutoin arvon epätosi. Kokeilkaamme nyt etsiä merkkijonosta "Aardvark advocacy" kirjainyhdistelmää "aa": print ereg("aa","aardvark advocacy",$array); print "<br>$array[0]<br>"; // tulostus: // 2 // aa Kirjaimet "aa" löytyivät merkkijonosta "aardvark", joten ereg() palauttaa arvon 2, joka on vastanneiden merkkien määrä. Myös taulukon $array ensimmäinen alkio täytetään vastanneella merkkijonolla, joka sitten tulostetaan selaimelle. Saattaa näyttää oudolta, että tiedämme jo, että hakemamme kuvio on "aa". Meidän ei kuitenkaan tarvitse hakea pelkästään ennalta määritettyjä merkkejä. Voisimme käyttää yksittäistä pistettä (.), joka vastaa mitä tahansa merkkiä: print ereg("d.","aardvark advocacy",$array); print "<br>$array[0]<br>"; // tulostus: // 2 // dv Nyt d. vastaa kirjainta "d", jonka jälkeen voi olla mikä tahansa merkki. Emme tiedä etukäteen, mikä tuo toinen merkki voi olla, joten nyt alkion $array[0] arvosta on hyötyä.

18. Säännöllisten lausekkeiden käyttäminen 321 Määrän ilmaiseminen Kun merkkiä haetaan merkkijonosta, voidaan käyttää apuna määrän ilmaisijaa, joka määrittää, kuinka monta kertaa kyseisen merkin tulee toistua, jotta merkkijoukko vastaa hakua. Esimerkiksi kuvio a+ vastaa vähintään yhtä "a"-kirjainta, jota seuraa nolla tai useampi "a". Kokeilkaamme tätä: if ( ereg("a+","aaaa", $array) ) print $array[0]; // tulostaa "aaaa"; Huomaa, että tämä säännöllinen lauseke vastaa mitä tahansa merkkimäärää. Taulukko 18.1 luettelee määrän ilmaisijat, joita voi siis käyttää toistuvien (peräkkäisten) merkkien hakemisessa. Taulukko 18.1 Määrän ilmaisija toistuvien merkkien haussa Symboli Kuvaus Esimerkki Vastaa Ei vastaa * Nolla tai useampi esiintymä a* xxxx Vastaa kaikkea + Yksi tai useampi esiintymä a+ xaax xxxx? Nolla tai useampi esiintymä a? xaxx xaax {n} n esiintymää a{3} xaaa aaaa {n,} Ainakin n esiintymää a{3,} aaaa aaxx {,n} Enintään n esiintymää a{,2} xaax aaax {n1,n2} Ainakin n1 esiintymää, mutta enintään n2 esiintymää a{1,2} xaax xaaa Taulukossa 18.1 olevien aaltosulkujen sisällä käytettyjä numeroita kutsutaan rajoiksi. Rajoilla voidaan määrittää tarkasti, kuinka monta kertaa merkin tulisi toistua, jotta se vastaisi hakua. Ylä- ja alarajat tulee asettaa aaltosulkuihin kohdemerkin jälkeen (esimerkiksi a{1,2}). Kokeilkaamme nyt esimerkkiä. Kerho on määrittänyt jäsenkoodit jäsenilleen. Sopiva koodi sisältää 1-4 "y"- kirjainta, jota seuraa jokin aakkosnumeerinen merkki ja sen jälkeen luku 99. Kerho on pyytänyt meitä jäsentelemään taustalokia ja ottamaan esille jäsenkoodit aina kun mahdollista. $test = "the code is yyxgdh99 -- have you received my sub?"; if ( ereg( "y{1,4}.*99 ", $test, $array ) ) print "Found membership: $array[0]"; // tulostaa "Found membership: yyxgdh99 " Nyt jäsenkoodi alkaa kahdella "y"-kirjaimella, joita seuraa neljä isoa kirjainta. Lopussa on luku 99. Lauseke y{1,4} vastaa kahta "y"-kirjainta ja lauseke.* vastaa isoja kirjaimia (vastaa mitä tahansa määrää mitä tahansa merkkejä). Olemmeko jo valmiita? No emme suinkaan. Taataksemme, että vastannut kuvio päättyy lukuun 99, olemme vaatineet välilyönnin viimeiseksi merkiksi. Se palautetaan, kun vastine löytyy. Entäpä, jos tutkittava merkkijono on seuraavanlainen?

322 18. Säännöllisten lausekkeiden käyttäminen "my code is yyxgdh99 did you get my 1999 sub?" Koodimme tuottaisi nyt seuraavan jäsenkoodin "y code is yyxgdh99 did you get my 1999" Mikä meni vikaan? Säännöllinen lausekkeemme vastasi "y"-kirjainta merkkijonossa "my" ja sen jälkeen mitä tahansa määrää merkkejä, kunnes kohdattiin luku 99, jota seurasi välilyönti. Säännölliset lausekkeet ovat ehdottomia. Ne vastaavat kaikkia mahdollisia merkkejä mitä vain voivat. Siitä syystä lausekkeemmekin vastaa kaikkia mahdollisia merkkejä, kunnes eteen tulee vuosiluvusta 1999 irrotettu 99, joka ei kuitenkaan ole osa jäsenkoodia. Voisimme yrittää parantaa tilannetta hieman määrittämällä, että merkkien "y" ja "99" välissä olevien merkkien tulee olla todella aakkosnumeerisia eivätkä ne sisällä välilyöntejä. Itse asiassa voimme toteuttaa sen merkkiluokan avulla. Merkkien määrittäminen merkkiluokilla Toistaiseksi olemme joko hakeneet tiettyjä merkkejä tai mitä tahansa merkkejä. Merkkiluokilla voidaan haku kohdentaa tiettyyn merkkiryhmään. Merkkiluokka määritetään laittamalla halutut vastemerkit hakasulkuihin. Merkintä [ab] vastaa joko merkkiä 'a' tai merkkiä 'b'. Kun olet luonut merkkiluokan, voit käsitellä sitä ikään kuin merkkinä. Niinpä [ab]+ vastaa merkkijonoja "aaa", "bbb" tai "ababab". Voit käyttää myös merkkien sarjaa merkkiluokassa: [a-b] vastaa kaikkia pikkukirjaimia, [A-Z] kaikkia isoja kirjaimia ja [0-9] kaikkia numeroita. Voit yhdistellä arvoalueita ja yksittäisiä merkkejä yhteen merkkiluokkaan, jolloin esimerkiksi [a-z5] vastaa merkkijonoja, jotka alkavat numerolla 5 ja joita seuraa pikkukirjain. Voit myös kääntää merkkiluokan laittamalla hattumerkin (^) heti vasemmanpuoleisen hakasulun jälkeen: [^A- Z] vastaa mitä tahansa muuta paitsi isoja kirjaimia. Katsokaamme nyt esimerkkiä edellisestä jaksosta. Meidän tulee löytää 1-4 kertaa esiintyvä 'y', mikä tahansa aakkosnumeerinen merkki, joka voi esiintyä kuinka monta kertaa tahansa, sekä merkit "99". $test = "my code is yyxgdh99 did you get my 1999 sub?"; if ( ereg( "y{1,4}[a-za-z0-9]*99 ", $test, $array ) ) print "Found membership: $array[0]"; // tulostaa "Found membership: yyxgdh99 " Lähestymme nyt ratkaisua. Merkkiluokka, jonka lisäsimme, ei enää vastaa välilyöntejä, joten jäsenkoodi palautetaan nyt. Jos kuitenkin lisäämme pilkun jäsenkoodin perään tekstiimme, säännöllinen lausekkeemme epäonnistuu jälleen: $test = "my code is yyxgdh99, did you get my 1999 sub?"; if ( ereg( "y{1,4}[a-za-z0-9]*99 ", $test, $array ) )

18. Säännöllisten lausekkeiden käyttäminen 323 print "Found membership: $array[0]"; // lauseke ei onnistu tehtävässään Tämä johtuu siitä, että olemme vaatineet välilyönnin kuvion perään varmistaaksemme, että olemme jäsenkoodin lopussa. Niinpä, jos tekstissä on hakasuluissa oleva jäsenkoodi tai koodi on ennen heittomerkkiä tai pilkkua, epäonnistumme jälleen. Voimme muokata lausekettamme, jotta se vastaa kaikkia muita merkkejä paitsi aakkosnumeerisia merkkejä, jolloin pääsemme lähemmäksi ratkaisua: $test = "my code is yyxgdh99, did you get my 1999 sub?"; if ( ereg( "y{1,4}[a-za-z0-9]*99[^a-za-z0-9]", $test, $array ) ) print "Found membership: $array[0]"; // tulostaa "Found membership: yyxgdh99," Olemme nyt lähempänä, mutta ongelmia ilmenee vieläkin. Ensiksikin, olemme lisänneet pilkun palautettuun vastineeseen ja toiseksi vasteen saaminen epäonnistuu, jos jäsenkoodi on testattavan merkkijonon lopussa, koska se vaatii, että jäsenkoodin perään on laitettu merkki. Toisin sanoen meidän on löydettävä luotettava keino testata sanan viereiset merkit. Palaamme tähän ongelmaan myöhemmin. Atomeilla työskentely Atomi on kuvio, joka laitetaan hakasulkuihin (sitä kutsutaan usein myös osakuvioksi). Kun olet määrittänyt atomin, voit käsitellä sitä ikään kuin se olisi merkki tai merkkiluokka. Toisin sanoen voit vastata samaa kuviota niin monta kertaa kuin haluat käyttämällä taulukossa 18.1 esitettyä syntaksia. Seuraava koodi määrittää kuvion, joka sijoitetaan hakasulkuihin ja lisäksi vaaditaan, että atomin tulee esiintyä kaksi kertaan, jotta se vastaisi lauseketta: $test = "abbaxabbaxabbax"; if ( ereg( "([ab]+x){2}", $test, $array ) ) sprint "$array[0]"; // tulostaa "abbaxabbax" Lauseke [ab]+x vastaisi merkkijonoa "abbax", mutta ([ab]+x)2 vastaa merkkijonoa "abbaxabbax". Taulukon, joka viedään ereg()-funktiolle, ensimmäinen alkio sisältää kokonaisen vastemerkkijonon. Peräkkäiset alkiot sisältävät kunkin yksittäisen vasteatomin. Tämä tarkoittaa sitä, että voit päästä käsiksi vastanneen kuvion komponentteihin sekä koko vasteeseen. Seuraavassa koodissa haemme IP-osoitetta ja tulostamme osoitteen eri osat: $test = "158.152.55.35"; if ( ereg( "([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)", $test, $array ) )

324 18. Säännöllisten lausekkeiden käyttäminen { foreach ( $array as $val ) print "$val<br>"; } // Tulostus: // 158.152.1.58 // 158 // 152 // 1 // 58 Huomaa, että olemme käyttäneet escape-merkkiä (kenoviivaa (\)) lausekkeissamme. Sillä tavoin määritämme, että haluamme ohittaa pisteen erikoismerkityksen ja kohdella sitä tavallisena merkkinä. Näin tulee tehdä kaikkien sellaisten merkkien kohdalla, joilla on erikoismerkitys säännöllisissä lausekkeissa, mikäli tuo erikoismerkitys halutaan kiertää. Haarautumat Voit yhdistää kuvioita putkella ( ) luodaksesi haarautumia säännöllisiin lausekkeisiisi. Säännöllinen lauseke, jossa on kaksi haaraa, vastaa joko ensimmäistä tai toista haaraa. Näin saat vielä lisää joustavuutta lausekkeisiisi. Seuraava koodi vastaa joko merkkijonoa ".com" tai merkkijonoa ".co.uk": $test = "www.adomain.com"; if ( ereg( "\.com \.co\.uk", $test, $array ) ) print "it is a $array[0] domain<br>"; // tulostaa "it is.com domain" Säännöllisen lausekkeen ankkurointi Sen lisäksi, että voit määrittää kuvion, jonka haluat löytää merkkijonosta, voit myös päättää, mistä kohtaa merkkijonoa haluat tuon kuvion löytää. Testataksesi, onko kuvio merkkijonon alussa, käytä lausekkeessasi hattumerkkiä (^). Kuvio ^a vastaa merkkijonoa "apple", mutta ei merkkijonoa "banana". Testataksesi, että kuvio on merkkijonon lopussa käytä taalamerkkiä ($) lausekkeesi lopussa. Tällöin kuvio a$ vastaa merkkijonoa "flea", mutta ei merkkijonoa "dear". Jäsenkoodiesimerkkimme uudelleen Meillä on nyt työkaluja jäsenkoodiesimerkkiemme täydentämiseen. Muista, että olemme jäsennelleet sähköposteja erottaaksemme jäsenkoodit, jotka koostuvat 1-4 'y'-kirjaimesta, joita seuraa vaihteleva määrä aakkosnumeerisia merkkejä ja sen jälkeen merkkijono "99". Nykyinen ongelmamme on siinä, kuinka määritämme, milloin vastannut kuvio on sanan alueella. Emme voi käyttää välilyöntiä, koska sanan molemmin puolin voi olla välimerkkejä. Emme voi vaatia, että jokin ei-aakkosnumeerinen merkki olisi sanan erottimena, koska kuviomme voi aloittaa tai päättää merkkijonon.

18. Säännöllisten lausekkeiden käyttäminen 325 Nyt kun voimme luoda haaroja ja ankkuroida kuvioita, voimme vaatia, että jäsenkoodin perässä voi olla joko ei-aakkosnumeerinen merkki tai merkkijonon loppu. Voimme käyttää samaa logiikkaa määrittämään sanan, joka esiintyy aluekoodin alussa. Voimme käyttää myös hakasulkuja havaitsemaan jäsenkoodin, jonka perässä on välilyöntejä tai välimerkkejä: $test = "my code is yyxgdh99, did you get my 1999 sub?"; if ( ereg( "(^ [^a-za-z0-9])(y{1,4}[a-za-z0-9]*99)([^a-za-z0-9] $)", $test, A $array ) ) print "Found membership: $array[2]"; // tulostaa "Found membership: yyxgdh99" Kuten voit nähdä, säännölliset lausekkeet ovat vaikeaselkoisia, ainakin ensi silmäyksellä. Kun jaat ne osiin, saat kuitenkin selville niiden salaisuudet. Olemme nyt varmistaneet, että kuviomme on sanan alueella. Tämä tarkoittaa sitä, että sen edellä tulee olla ei-aakkosnumeerinen merkki tai sen tulee olla merkkijonon alku. Sen perässä tulee myös olla aakkosnumeerinen merkki tai merkkijonon loppu. Emme halua tallentaa edellä tai perässä olevia merkkejä, joten laitamme kuviomme hakasulkuihin. Siten voimme olla varmoja siitä, että haluttu kohde on taulukkomme ($array) toisena alkiona. Ereg() erottelee isot ja pienet kirjaimet. Jos et halua niin tapahtuvan, käytä eregi()-funktiota. Se ei erottele isoja ja pieniä kirjaimia, mutta toimii muutoin täysin samalla lailla kuin ereg(). Merkkijonojen korvaaminen egrep_replace()-funktiolla Toistaiseksi olemme etsineet kuvioita merkkijonosta muuttamatta merkkijonoa. Uusi egrep_replace()- funktio mahdollistaa kuvion hakemisen ja korvaamisen uudella osamerkkijonolla. Funktio ottaa kolme argumenttia: säännöllisen ilmauksen, tekstin, joka korvaa löydetyn kuvion ja muunnettavan tekstin. Funktio palauttaa merkkijonon, jos muokkaus on onnistunut. Jos haku ja korvaus eivät onnistu, palautetaan alkuperäinen kohdemerkkijono. Seuraavassa koodissa etsimme kerhon sihteerin nimeä ja korvaamme sen seuraavana olevan jäsenen nimellä: $test = "Our Secretary, Sarah Williams is pleased to welcome you."; print ereg_replace("sarah Williams", "Rev. P.W. Goodchild", $test); // tulostaa "Our Secretary, Rev. P.W. Goodchild is pleased to welcome you." Huomaa, että vaikka ereg() vastaa vain ensimmäistä löytämäänsä kuviota, se korvaa kaikki vastaavat esiintymät.

326 18. Säännöllisten lausekkeiden käyttäminen Taaksepäin viittaaminen egrep_replace()-funktiolla Taaksepäin viittaaminen mahdollistaa vastatun kuvion osan käyttämisen merkkijonon muuttamiseen. Tätä ominaisuutta käytettäessä tulee käyttää sulkumerkkejä ottamaan esille kaikki ne säännöllisen ilmauksen alkiot, joita halutaan käyttää. Näiden osakuvioiden kautta löydetty teksti on korvaavan merkkijonon käytettävissä, jos viittaat niihin kahdella kenoviivalla ja atomin numerolla (esimerkiksi \\1). Atomit numeroidaan järjestyksessä, ulommista sisään päin, vasemmalta oikealle alkaen arvosta \\1. Merkintä \\0 tallentaa koko vastineen. Seuraava koodi muuntaa päivämäärät, jotka ovat muodossa pp/kk/vv muotoon kk/pp/vv: $test = "25/12/2000"; print ereg_replace("([0-9]+)/([0-9]+)/([0-9]+)", "\\2/\\1/\\3", $test); // tulostaa "12/25/2000" Ereg_replace() tunnistaa isot ja pienet kirjaimet. Jos et halua niin tapahtuvan, voit käyttää Eregi_replace()-funktiota, joka ei tunnista isoja ja pieniä kirjaimia, mutta on muutoin samanlainen kuin ereg_replace(). Merkkijonojen pilkkominen split()-funktiolla Luvussa 17 kerrottiin, kuinka merkkijono voitiin jakaa osiin, jotka laitettiin taulukkoon funktiolla explode(). Kyseessä on tehokas menettely, mutta siinä voidaan antaa vain yksi merkkijoukko erottimeksi. PHP4:n split()-funktio mahdollistaa säännöllisten lausekkeiden hyödyntämisen määrittämään joustava erotin. Funktio ottaa argumenteikseen merkkijonon, joka edustaa erotinkuviota, ja lähdemerkkijonon. Se hyväksyy myös valinnaisen kolmannen argumentin, joka edustaa palautettavien alkioiden lukumäärää. Funktio palauttaa taulukon. Seuraava koodi käyttää säännöllistä lauseketta, jossa on kaksi erotinta; erottimena voi olla pilkku tai sana "and", jonka molemmin puolin on välilyönti: $text = "apples, oranges, peaches and grapefruit"; $fruitarray = split( ", and ", $text ); foreach ( $fruitarray as $item ) print "$item<br>"; // tulostus: // apples // oranges // peaches // grapefruit

18. Säännöllisten lausekkeiden käyttäminen 327 Perl-yhteensopivat säännölliset lausekkeet Jos siirryt Perl-maailmasta PHP:n käyttämiseen, tuntuvat POSIX-yhteensopivat lausekkeet varmaankin oudoilta. Hyvä uutinen onkin nyt se, että PHP4 tukee Perl-yhteensopivia säännöllisiä ilmauksia. Ne ovat jopa tehokkaampia kuin aiemmin esitetyt menettelyt. Tutkimme nyt näitä eroja. Kuvioiden hakeminen preg_match()-funktiolla Funktio preg_match() ottaa kolme argumenttia: säännöllisen lausekkeen, lähdemerkkijonon ja taulukkomuuttujan, johon vastineet tallennetaan. Funktio palauttaa arvon tosi, jos vastine löytyy, mutta muutoin arvon epätosi. Tämän funktion ja ereg_match()-funktion ero on säännöllisessä lausekkeessa. Perl-yhteensopivat säännölliset lausekkeet tulee laittaa erottimien sisälle. Yleensä nuo erottimet ovat kauttaviivoja, vaikkakin niiden sijaan voidaan käyttää mitä tahansa merkkiä. Seuraava koodi käyttää tätä funktiota hakemaan merkkijonosta merkkiä p, jota voi seurata mikä tahansa merkki, jonka jälkeen seuraa kirjain t: $text = "pepperpot"; if ( preg_match( "/p.t/", $text, $array ) ) print $array[0]; // tulostaa "pot" Perl-lausekkeet käytössä Oletuksena säännölliset ilmaukset koettavat vastata niin montaa merkkiä kuin mahdollista. Niinpä lauseke "/p.*t/" hakee ensimmäistä 'p'-merkkiä merkkijonosta ja vastaa niin montaa merkkiä kuin mahdollista kunnes viimeinen 't'-merkki kohdataan. Niinpä tämä säännöllinen lauseke vastaa koko testimerkkijonoa seuraavassa koodissa: $text = "pot post pat patent"; if ( preg_match( "/p.*t/", $text, $array ) ) print $array[0]; // tulostaa "pot post pat patent" Sijoittamalla kysymysmerkin (?) määrän ilmaisijan jälkeen voidaan Perl-lauseke pakottaa toimimaan kontrolloidummin. Lauseke "p.*t"

328 18. Säännöllisten lausekkeiden käyttäminen tarkoittaa "p-kirjainta, jota seuraa niin monta merkkiä kuin mahdollista ja sen jälkeen tulee kirjain t". Lauseke "p.*?t" tarkoittaa "p-kirjainta, jota seuraa niin vähän kirjaimia kuin mahdollista ja sen jälkeen tulee kirjain t" Seuraava koodi käyttää tätä tekniikkaa vastaamaan pienintä kirjainmäärää, jossa ensimmäisenä kirjaimena on 'p' ja viimeisenä kirjaimena 't': $text = "pot post pat patent"; if ( preg_match( "/p.*?t/", $text, $array ) ) print $array[0]; // tulostaa "pot" Perl-lausekkeet ja kenoviivalla merkityt merkit Joitakin merkkejä voidaan ohittaa Perl-lausekkeissa samalla lailla kuin merkkijonoissa. Esimerkiksi merkintä \t tarkoittaa tabulaattorimerkkiä ja \n uutta riviä. Myös Perl-lausekkeissa voidaan käyttää escape-merkkiä; tällöin lauseke vastaa kokonaista merkkityyppiä. Taulukko 18.2 luettelee nämä kenoviivamerkit. Taulukko 18.2 Escape-merkit, jotka vastaava merkkityyppejä Merkki Vastaa \d Mikä tahansa numero \D Mikä tahansa muu kuin numero \s Mikä tahansa tyhjä merkki (white space) \S Mikä tahansa muu kuin tyhjä merkki \w Mikä tahansa kirjain (myös alaviiva mukana) \W Mikä tahansa muu kuin kirjain Nämä escape-merkit voivat yksinkertaistaa säännöllisiä lausekkeita suunnattomasti. Ilman niitä joutuisit kirjoittamaan merkkiluokan rajat. Vertaa ereg()- ja preg_match()-funktioiden käyttöä kirjainten hakemisessa: ereg( "p[a-za-z0-9_]+t", $text, $array ); preg_match( "/p\w+t/, $text, $array );

18. Säännöllisten lausekkeiden käyttäminen 329 Perl-lausekkeet tukevat myös monia escape-merkkejä, jotka toimivat ankkureina. Ankkurit vastaavat sijainteja merkkijonossa vastaamatta mitään merkkejä. Nämä ankkurit luetellaan taulukossa 18.3. Taulukko 18.3 Escape-merkit, jotka toimivat ankkureina Merkki Vastaa \A Merkkijonon alku \b Sanan rajat \B Ei sanan rajat \Z Merkkijonon loppu (ennen viimeistä rivinvaihtoa tai loppumerkkiä) \z Merkkijonon loppu (vain merkkijonon lopussa) Muista ongelmat, joita meillä oli sanarajojen hakemisessa jäsenkoodiesimerkissämme. Perlin mukaiset lausekkeet helpottavat tätä työtä. Vertaa ereg()- ja preg_match()-syntakseja, kun haetaan sanan merkkejä ja rajoja: ereg( "(^ [^a-za-z0-9_])(p[a-za-z0-9_]+t)([^a-za-z0-9_] $)", $text, $array ); preg_match( "\bp\w+t\b", $text, $array ); Esimerkkikoodissamme preg_match() vastaa merkkiä "p", mutta vain jos se on sanan rajana, jolloin sitä seuraa merkkejä ja lopuksi kirjain "t", mutta vain silloin, kun "t" on sanan rajamerkkinä. Sanan rajana oleva escape-merkki ei todellisuudessa vastaa kirjainta; se pelkästään vahvistaa, että raja esiintyy. Jos käyttäisit ereg_match()-funktiota, sinun tulisi muodostaa kuvio muille merkeille ja vastattava joko sitä tai merkkijonorajoja. Voit myös ohittaa kirjaimia muuttaaksesi niiden merkityksiä. Vastataksesi esimerkiksi kirjainta "." sinun tulisi lisätä kenoviiva sen eteen. Vasteiden etsiminen globaalisti preg_match_all()-funktiolla Eräs POSIX-mukaisten säännöllisten lausekkeiden ongelma on se, että on vaikeaa vastata jokaista kuvion esiintymää merkkijonossa. Niinpä käytettäessä ereg()-funktiota hakemaan sanoja, jotka alkavat kirjaimella "p" ja päättyvät kirjaimeen "s", löydetään vain ensimmäinen tapaus. Kokeilkaamme: $text = "I sell pots, plants, pistachios, pianos and parrots"; if ( ereg( "(^ [^a-za-z0-9_])(p[a-za-z0-9_]+s)([^a-za-z0-9_] $)", $text, $array ) ) { for ( $x=0; is_string( $array[$x] ); $x++ ) print "\$array[$x]: $array[$x]<br>\n"; } // tulostus:

330 18. Säännöllisten lausekkeiden käyttäminen // $array[0]: pots, // $array[1]: // $array[2]: pots // $array[3]:, Kuten odotimme, ensimmäinen löytömme "pots" tallennetaan $array-taulukon kolmanteen alkioon. Ensimmäinen alkio sisältää täydellisen vastineen, toinen taas välilyönnin ja neljäs pilkun. Saadaksesi jokaisen kuvion esille, meidän tulisi käyttää ereg_replace()-funktiota silmukassa poistamaan jokainen löydetty vaste ennen seuraavaa hakua. Voimme käyttää preg_match_all()-funktiota jokaisen vastineen löytämiseksi samalla kertaa kohdemerkkijonosta. Funktio ottaa argumenteikseen säännöllisen ilmauksen, lähdemerkkijonon, taulukkomuuttujan ja palauttaa arvon tosi, jos vaste löytyy. Taulukkomuuttuja täytetään moniulotteiseilla taulukolla, jonka ensimmäinen alkio sisältää jokaisen vasteen. Listaus 18.1 testaa merkkijonon käyttämällä preg_match_all()-funktiota; koodissa on kaksi for-silmukkaa, jotka tulostavat tuloksena olevan moniulotteisen taulukon. Listaus 18.1 Kuviovasteen hakeminen globaalisti preg_match_all()-funktiolla 1: <html> 2: <head> 3: <title>using preg_match_all() to match a pattern globally</title> 4: </head> 5: <body> 6: <?php 7: $text = "I sell pots, plants, pistachios, pianos and parrots"; 8: if ( preg_match_all( "/\bp\w+s\b/", $text, $array ) ) 9: { 10: for ( $x=0; $x< count( $array ); $x++ ) 11: { 12: for ( $y=0; $y< count( $array[$x] ); $y++ ) 13: print "\$array[$x][$y]: ".$array[$x][$y]."<br>\n"; 14: } 15: } 16: // Tulostus: 17: // $array[0][0]: pots 18: // $array[0][1]: plants 19: // $array[0][2]: pistachios 20: // $array[0][3]: pianos

18. Säännöllisten lausekkeiden käyttäminen 331 21: // $array[0][4]: parrots 22:?> 23: </body> 24: </html> Funktiolle preg_match_all() viedään $array-taulukko; siinä on vain yksi alkio, merkkijonotaulukko. Tämä taulukko sisältää testimerkkijonon kaikki sanat, jotka alkavat kirjaimella "p" ja päättyvät kirjaimeen "s". Funktio preg_match_all() täyttää moniulotteisen taulukon osakuvioiden vasteilla. Ensimmäinen alkio sisältää koko säännöllisen lausekkeen jokaisen vasteen. Kukin lisäalkio sisältää osamerkkijonojen vasteet. Niinpä seuraavassa kutsussa preg_match_all() $text = "01-05-99, 01-10-99, 01-03-00"; preg_match_all( "/(\d+)-(\d+)-(\d+)/", $text, $array ); $array[0] tallentaa täysien vasteiden taulukon: $array[0][0]: 01-05-99 $array[0][1]: 01-10-99 $array[0][2]: 01-03-00 $array[1] tallentaa ensimmäisen osamerkkijonon vastetaulukon: $array[1][0]: 01 $array[1][1]: 01 $array[1][2]: 01 $array[2] tallentaa toisen osamerkkijonon vastetaulukon: $array[2][0]: 05 $array[2][1]: 10 $array[2][2]: 03 ja niin edelleen.

332 18. Säännöllisten lausekkeiden käyttäminen Kuvioiden korvaaminen preg_replace()-funktiolla Tämä preg_replace()-funktio käyttäytyy täysin samalla tavalla kuin ereg_replace(), paitsi että sen kautta päästään käsiksi Perl-yhteensopivien säännöllisten lausekkeiden lisätoiminnallisuuteen. Funktio ottaa argumenteikseen säännöllisen ilmauksen, korvaavan merkkijonon ja lähdemerkkijonon. Jos vaste löytyy, se palauttaa muunnetun merkkijonon; muutoin se palauttaa lähdemerkkijonon kopion. Seuraava koodi muuntaa merkkijonon päivämäärät muodosta pp/mm/vv muotoon kk/pp/vv: $t = "25/12/99, 14/5/00"; $t = preg_replace( " \b(\d+)/(\d+)/(\d+)\b ", "\\2/\\1/\\3", $t ); print "$t<br>"; // tulostaa "12/25/99, 5/14/00" Huomaa, että käytimme edellä putkisymbolia ( ) erottimena. Sen ansiosta meidän ei tarvitse ohittaa kauttaviivan merkitystä kuviossamme. Funktio tukee viittauksia taaksepäin ssamalla lailla kuin ereg_replace()-funktio. Lähdemerkkijonon sijaan preg_match-funktiolle voidaan viedä merkkijonotaulukko ja se osaa muuntaa taulukon jokaisen merkkijonon. Tässä tapauksessa palautusarvo on muunnetut merkkijonot sisältävä taulukko. Voit viedä preg_match()-funktiolle myös taulukoita, joissa on säännöllisiä lausekkeita ja korvaavia merkkijonoja. Kutakin säännöllistä lauseketta käytetään lähdemerkkijonoon ja suoritetaan sitten vastaava korvaaminen. Seuraava koodi muuntaa päivämäärämuodot samalla lailla kuin ennenkin, mutta muuttaa myös kopio-oikeus-informaation lähdemerkkijonossa: $text = "25/12/99, 14/5/00. Copyright 1999"; $regs = array( " \b(\d+)/(\d+)/(\d+)\b ", "/([Cc]opyright) 1999/" ); $reps = array( "\\2/\\1/\\3", "\\1 2000" ); $text = preg_replace( $regs, $reps, $text ); print "$text<br>"; // tulostaa "12/25/99, 5/14/00. Copyright 2000" Luomme kaksi taulukkoa. Ensimmäinen, $regs, sisältää kaksi säännöllistä lauseketta ja toinen, $reps, sisältää korvaavat merkkijonot. Ensimmäinen $reps-taulukon alkio vastaa ensimmäistä $regs-taulukon alkiota jne. Jos korvaavien merkkijonojen taulukko sisältää vähemmän alkioita kuin säännöllisten lausekkeiden taulukko, tapahtuu vasteiden korvaaminen tyhjillä merkkijonoilla. Jos preg_replace()-funktiolle viedään säännöllisten lausekkeiden taulukko, mutta vain yksi korvaava merkkijono, käytetään tuota yhtä merkkijonoa kaikissa korvaamisissa. Muuntimet Perl-yhteensopivat säännölliset lausekkeet ovat joustavia; kuvioiden käyttötapa on muunneltavissa.

18. Säännöllisten lausekkeiden käyttäminen 333 Kuvion muuntaja on kirjain, joka sijoitetaan lopullisen erottimen jälkeen Perl-yhteensopivissa säännöllisissä lausekkeissa. Tuo muunnin muuttaa lausekkeen käyttäytymistä. Taulukko 18.4 luettelee Perl-lausekkeiden kuviomuuntimet. Taulukko 18.4 Perl-yhteensopivien säännöllisten lausekkeiden muuntimet Kuvio Kuvaus /i Isoja ja pieniä kirjaimia ei erotella /e Käsittelee preg_replace()-funktion korvaavaa merkkijonoa PHPkoodina /m Ankkurit $ ja ^vastaavat nykyisen rivin alkua ja loppua /s Vastaa rivinvaihtoja (piste ei normaalisti vastaa rivinvaihtoa) /x Merkkiluokkien ulkopuolella olevaa välilyöntiä ei vastata luettavuuden takia. Jos 'white space'-alueita halutaan vastata, tulee käyttää menettelyjä \s, \t tai \. /A Vastaa kuviota vain merkkijonon alussa (ei mukana Perlissä) /E Vastaa kuviota vain merkkijonon lopussa (ei mukana Perlissä) /U Tarkennus, jossa minimimäärä sallittuja vasteita löydetään (ei mukana Perlissä) Kuviomuuntimia voidaan myös yhdistellä. Saatat esimerkiksi haluta käyttää x-muunninta tekemään lausekkeista helppolukuisempia ja lisätä mukaan i-muuntimen, jolloin haussa ei erotella isoja ja pieniä kirjaimia. Esimerkiksi kuvio / b \S* t /ix vastaa merkkijonoja "bat" ja "BAT", mutta ei merkkijonoa "B AT". Huomaa, että itse kuviossa voi olla luettavuuden takia välilyöntejä; niitä ei oteta haussa huomioon. Muunninta m voidaan käyttää silloin, kun halutaan vastata ankkuroitua kuviota useilla tekstiriveillä. Ankkurikuviot ^ja $ vastaavat oletuksena koko merkkijonon alkua ja loppua. Seuraava koodi käyttää m- muunninta $-ankkurin käyttäytymisen muuttamiseen: $text = "name: matt\noccupation: coder\neyes: blue\n"; preg_match_all( "/^\w+:\s+(.*)$/m", $text, $array ); foreach ( $array[1] as $val ) print "$val<br>"; // tulostus: // matt // coder // blue Luomme säännöllisen lausekkeen, joka vastaa mitä tahansa sanaa, jota seuraa kaksoispiste ja mikä tahansa määrä välilyöntejä. Muunnin s on hyödyllinen, jos halutaan käyttää pistettä (.) vastaamaan merkkejä useilla riveillä. Seuraava koodi koettaa päästä käsiksi merkkijonon ensimmäiseen ja viimeiseen sanaan:

334 18. Säännöllisten lausekkeiden käyttäminen $text = "start with this line\nand you will reach\na conclusion in the end\n"; preg_match( "/^(\w+).*?(\w+)$/", $text, $array ); print "$array[1] $array[2]<br>"; Tämä koodi ei tulosta mitään. Vaikka säännöllinen lauseke löytää merkit merkkijonon alusta, ei piste (.) kuitenkaan vastaa rivinvaihtomerkkejä, jotka on upotettu tekstiin. Seuraavassa parannamme tilanteen s- muuntimen avulla: $text = "start with this line\nand you will reach\na conclusion in the end\n"; preg_match( "/^(\w+).*?(\w+)$/s", $text, $array ); print "$array[1] $array[2]<br>"; // tulostaa "start end" Muunnin e on erityisen tehokas. Se mahdollistaa preg_replace()-funktiossa olevan korvaavan merkkijonon käsittelyn ikäänkuin se olisi PHP-koodia. Voit viedä funktioille esimerkiksi taaksepäin viittauksia argumentteina tai käsitellä numeroluetteloita. Seuraavassa esimerkissä käytämme e-muunninta viemään päivämääränumerot funktiolle, joka palauttaa päivämäärän uudelleen muotoiltuna. <?php function convdate( $month, $day, $year ) { $year = ($year < 70 )?$year+2000:$year; $time = ( mktime( 0,0,0,$month,$day,$year) ); return date("l F Y", $time); } $dates = "3/18/99<br>\n7/22/00"; $dates = preg_replace( "/([0-9]+)\/([0-9]+)\/([0-9]+)/e", "convdate(\\1,\\2,\\3)", $dates); print $dates; // tulostaa: // Thursday 18 March 1999 // Saturday 22 July 2000?>

18. Säännöllisten lausekkeiden käyttäminen 335 Koodi löytää minkä tahansa kolmen numeron joukon, joiden erottimina on kauttaviivat, käyttämällä sulkumerkkejä sieppaamaan vastanneet numerot. Koska käytämme e-muunninta, voimme kutsua käyttäjän määrittelemää convdate()-funktiota korvaavan merkkijonon kautta ja viedä funktiolle kolme taaksepäin viittausta. Tuo convdate() yksinkertaisesti muokkaa numeroarvot luettavampaan päivämäärämuotoon. Yhteenveto Säännölliset lausekkeet ovat hyvin laaja aihe ja olemme todellakin nähneet vain osan niiden tehosta tällä tunnilla. Siitä huolimatta sinun tulisi nyt osata käyttää säännöllisiä lausekkeita hakemaan ja korvaamaan monimutkaisia kuvioita tekstistä. Sinun tulisi osata käyttää ereg()-funktiota hakemaan kuvioita merkkijonoista ja ereg_replace()-funktiota korvaamaan kaikki kuvioesiintymät merkkijonosta. Olemme myös opastaneet sinua hakemaan merkkialueita merkkiluokkien avulla, useita kuvioita määräilmaisimien avulla ja vaihtoehtoisia kuvioita haarautumien avulla. Sinun tulisi nyt osata myös erottaa osamerkkijonot ja viitata niihin taaksepäin viittauksilla. Perlyhteensopivien säännöllisten lausekkeiden avulla sinun tulisi osata käyttää escape-merkkejä ankkuroimaan kuvioita tai vastaamaan merkkityyppejä. Sinun tulisi osata myös käyttää muuntimia muuttamaan tapaa, jolla Perl-yhteensopivat lausekkeet toimivat. K&V K Perl-yhteensopivat säännölliset lausekkeet näyttävät hyvin tehokkailta. Mistä voin saada niistä lisätietoa? V PHP-manuaalista (http://www.php.net) saat lisätietoa. Hyödyllisiä paikkoja voivat olla myös http://www.perl.com, erityisesti http://www.perl.com/pub/doc/manual/html/pod/perlre.html ja Tom Christiansenin artikkeli osoitteessa http://www.perl.com/pub/doc/manual/html/pod/ perlfaq6.html. Työpaja Työpaja tarjoaa pikakysymyksiä, joiden avulla voit kerrata läpikäytyä materiaalia. Yritä ymmärtää vastaukset ennen kuin jatkat seuraavaan lukuun. Vastaukset annetaan liitteessä A. Kysymyksiä 1. Mitä POSIX-funktiota käyttäisit vastaamaan kuviota merkkijonossa? 2. Millä säännöllisellä lausekkeella voisit hakea merkkijonosta kirjainta "b", kun kirjain voi esiintyä 1-6 kertaa? 3. Kuinka määrittäisit merkkialueen, joka on väliltä "d" ja "f"? 4. Kuinka tekisit kysymyksen 3 merkkialueesta käänteisen? 5. Millä syntaksilla voisit vastata joko mitä tahansa numeroa tai sanaa "tree"? 6. Mitä POSIX-lauseketta käyttäisit korvaamaan vastanneen kuvion? 7. Säännöllinen lauseke.*bc vastaa pikemminkin merkkijonoa "abc000000bc" kuin merkkijonoa "abc". Kuinka muuttaisit lauseketta niin, että se vastaisi vain ensimmäistä löydettyä esiintymää?

336 18. Säännöllisten lausekkeiden käyttäminen 8. Millaisella Perl-yhteensopivalla lausekkeella voisit vastata 'white space'.-merkkiä? 9. Millaisella Perl-yhteensopivalla funktiolla voisit vastata kuvion jokaista esiintymää? 10. Mitä muunninta käyttäisit Perl-yhteensopivassa funktiossa voidaksesi ohittaa haussa isojen ja pienten kirjainten erottelun? Toiminta 1. Käytä säännöllisiä lausekkeita erottamaan email-osoitteita tiedostosta. Lisää ne taulukkoon ja tulosta selaimelle.