17. Merkkijonoilla työskentely 301 OPPITUNTI 17 Merkkijonoilla työskentely World Wide Web on paljolti pelkkä tekstiympäristö. Olipa sisältö kuinka monipuolista tahansa, kaiken takana on aina HTML-koodi. Niinpä ei olekaan sattuma että PHP4 tarjoaa käyttöön useita funktioita, joilla voit muotoilla, tutkia ja muokata merkkijonoja. Tämän tunnin aiheita ovat seuraavat: Kuinka merkkijonoja muotoillaan Kuinka määritetään merkkijonon pituus Kuinka löydetään osamerkkijono merkkijonosta Kuinka merkkijono pilkotaan komponentteihin Kuinka merkkijonon alusta ja lopusta poistetaan tyhjä tila (white space) Kuinka merkkijonoja vaihdetaan Kuinka merkkijonon kirjaimet muunnetaan isoiksi tai pieniksi
302 17. Merkkijonoilla työskentely Merkkijonojen muotoilu Toistaiseki olemme vain tulostaneet merkkijonoja selaimelle. PHP sisältää kaksi funktiota, joilla kohde voidaan muotoilla eri tavoin: esimerkiksi desimaaliluvun desimaalien määrä voidaan päättää, kentän asettelu voidaan määrittää halutuksi tai tieto voidaan esittää toisessa lukujärjestelmämuodossa. Tässä jaksossa tutkimme, mitä muotoilumahdollisuuksia printf()- ja sprintf()-funktiot tarjoavat. Muotoileva tulostus printf()-funktiolla Jos olet käyttänyt aiemmin C-kieltä, olet jo tutustunut printf()-funktioon. PHP-versio on samanlainen, mutta ei identtinen. Funktio ottaa argumentikseen muotoilumerkkijonon ja eri tyyppisiä valinnaisia lisäargumentteja. Muotoilumerkkijono sisältää ohjeet, joiden mukaan nuo lisäargumentit esitetään. Esimerkiksi seuraava koodi käyttää printf()-funktiota kokonaisluvun tulostamiseksi kymmenjärjestelmälukuna: printf("this is my number: %d", 55 ); // tulostaa "This is my number: 55" Muotoilumerkkijonon sisällä (ensimmäinen argumentti) on nyt erikoiskoodi, jota kutsutaan muunnosmäärittelyksi. Muunnosmäärittely alkaa prosenttimerkillä (%) ja se määrittää, kuinka funktion vastaava argumentti muotoillaan. Muotoilumerkkijonoon voidaan laittaa haluttu määrä muunnosmäärittelyjä, kunhan vastaava määrä argumentteja on mukana funktiossa. Seuraava koodi tulostaa kaksi lukua printf()-funktion avulla: printf("first number: %d<br>\nsecond number: %d<br>\n", 55, 66 ); // Tulostus: // First number: 55 // Second number: 66 Ensimmäinen muunnosmäärittely vastaa ensimmäistä lisäargumenttia, joka on nyt 55. Toinen muunnosmäärittely vastaa lukua 66. Prosenttisymbolia seuraava merkki 'd' vaatii, että kohdetietoa käsitellään kymmenjärjestelmän kokonaislukuna. Tämä muunnosmäärittelijän osa on tyypin määrittäjä. Tyypin määrittäjä printf()-funktiossa Olet jo tavannut yhden tyypinmäärittäjän, merkin 'd', joka esittää tiedon kokonaislukuna. Taulukko 17.1 luettelee muut tyypin määrittäjät.
17. Merkkijonoilla työskentely 303 Taulukko 17.1 Tyypin määrittäjät Tyypin määrittäjä Kuvaus d Kohde esitetään kymmenjärjestelmän kokonaislukuna b Kohde esitetään binäärilukuna c Kohde esitetään ASCII-merkkinä f Kohde esitetään desimaalilukuna (double) o Kohde esitetään oktaalilukuna (kantaluku on 8) s Kohde esitetään merkkijonona x Kohde esitetään heksadesimaalimuodossa pienin kirjaimin (kantaluku on 16) X Kohde esitetään heksadesimaalimuodossa isoin kirjaimin (kantaluku on 16) Listaus 17.1 käyttää printf()-funktiota esittämään yksittäisen luvun käyttämällä muutamia taulukossa olevia tyypin määrittäjiä. Huomaa, että emme vain lisänneet muunnosmäärittelyjä muotoilumerkkijonoon. Myös kaikki mukana oleva lisäteksti tulostetaan. Listaus 17.1 Muutaman tyypin määrittäjän esitteleminen 1: <html> 2: <head> 3: <title>demonstrating some type specifiers</title> 4: </head> 5: <body> 6: <?php 7: $number = 543; 8: printf("decimal: %d<br>", $number ); 9: printf("binary: %b<br>", $number ); 10: printf("double: %f<br>", $number ); 11: printf("octal: %o<br>", $number ); 12: printf("string: %s<br>", $number ); 13: printf("hex (lower): %x<br>", $number ); 14: printf("hex (upper): %X<br>", $number ); 15:?> 16: </body> 17: </html> Kuva 17.1 näyttää koodin tulostuksen. Kuten näet, printf() on näppärä keino muuntaa tieto toisesta järjestelmästä toiseen.
304 17. Merkkijonoilla työskentely KUVA 17.1 Muunnosmäärittäjien esittely. Kun määrittelet värin HTML-koodilla, yhdistät kolme heksadesimaalinumeroa, jotka ovat väliltä 00 - FF. Nuo kolme lukua esittävät punaisen, vihreän ja sinisen värin osuuksia. Voit käyttää printf()-funktiota muuntamaan värejä vastaavat kymmenjärjestelmäluvut, jotka ovat väliltä 0-255, vastaaviksi heksadesimaaliluvuiksi. Seuraavassa on esimerkkikoodi: $red = 204; $green = 204; $blue = 204; printf( "#%X%X%X", $red, $green, $blue ); // tulostaa "#CCCCCC" Vaikka voitkin käyttää näitä tyypin määrittäjiä muuntamaan kymmenjärjestelmän lukuja heksadesimaalimuotoon, et voi käyttää niitä määrittämään, kuinka monta merkkiä käytetään kunkin argumentin tulostuksessa. HTML-värikoodissa kukin väri esitetään kahdella numerolla, joten koodimme aiheuttaisi ongelmia, jos kohteena oleva luku voidaan esittää yhdellä heksadesimaalinumerolla. Jos muuttujissa $red, $green ja $blue on arvo 1, olisi vastaava heksadesimaaliluku "#111". Voimme pakottaa etunollien esittämisen tilan määrittäjällä. Tulostustilan määrittäminen tilan määrittäjällä Voit määrittää tulostuksen sellaiseksi, että eteen tulee haluttuja etumerkkejä. Tilan määrittäjä tulee sijoittaa heti prosenttimerkin jälkeen. Jos tulostukseen halutaan etunollat, tulee tilan määrittäjään sijoittaa nolla, jota seuraa tulostuksessa käytettävän tilan koko. Jos tulostuksessa käytetään tilaa vähemmän kuin kyseinen tilan koko, täytetään etuosa nollilla: printf( "%04d", 36 ); // tulostaa "0036" Jos eteen halutaan välilyöntejä, tarvitsee tilan määrittäjään vain lisätä nollan sijaan välilyönti, jota sitten seuraa tulostuksessa käytettävän tilan koko:
17. Merkkijonoilla työskentely 305 printf( "% 4d", 36 ) // tulostaa " 36" Selain ei esitä toistuvia välilyöntejä HTML-asiakirjassa. Voit pakottaa välilyönnit ja rivinvaihdot esitettäviksi laittamalla tekstisi <PRE>-tagien sisälle. <pre> <?php print "The spaces will be visible";?> </pre> Jos haluat muotoilla koko asiakirjan tekstiksi, voit käyttää header()-funktiota muuttamaan Content-Type-otsikko: header("content-type: Text/Plain"); Muista, että skriptisi ei saa lähettää mitään tulostusta selaimelle, jotta tämä header()-temppu onnistuisi. Etunollan sijaan voit määrittää minkä tahansa merkin; tällöin merkki laitetaan heittomerkkien sisälle: printf ( "%'x4d", 36 ); // tulostaa "xx36" Nyt meillä on työkaluja HTML-koodiesimerkkimme täydentämiseksi. Toistaiseksi olemme voineet muuntaa kolme numeroa heksadesimaaleiksi, mutta emme ole voineet ottaa mukaan etunollia: $red = 1; $green = 1; $blue = 1; printf( "#%02X%02X%02X", $red, $green, $blue ); // tulostaa "#010101"
306 17. Merkkijonoilla työskentely Kukin muuttuja tulostetaan heksadesimaalimuodossa. Jos tulostus vie tilaa vähemmän kuin kaksi merkkiä, lisätään etunollat. Kentän leveyden määrittäminen Voit määrittää merkkien määrän, johon tulostuksen tulee sovittautua. Kentänleveysmäärittäjä on kokonaisluku, joka tulee sijoittaa muunnosmäärittäjässä prosenttimerkin jälkeen (olettaen, että mitään etumerkin määrittäjää ei ole määritetty). Seuraava koodi tulostaa neljä kohdetta, joista jokainen käyttää 20 merkkiä tilaa. Jotta tila näkyisi myös selaimessa, on koodiin lisätty PRE-elementti: print "<pre>"; printf("%20s\n", "Books"); printf("%20s\n", "CDs"); printf("%20s\n", "Games"); printf("%20s\n", "Magazines"); print "</pre>"; Kuva 17.2 esittää koodin tulostuksen. KUVA 17.2 Asettelu kentänleveysmäärittäjiä käyttäen. Oletuksena tulostus käyttää oikean reunan tasausta määritetyn kentän sisällä. Voit ottaa käyttöön vasemman reunan tasauksen lisäämällä väliviivan (-) kentänleveysmäärittäjään: printf("%-20s\n", "Left aligned"); Huomaa, että asettelu kohdistuu vain tulostuskohteen desimaaliosaan. Toisin sanoen vain desimaalipisteen vasemmalla puolella oleva osa sijoittuu tulostuskenttään, kun oikean reunan tasaus on päällä.
17. Merkkijonoilla työskentely 307 Tarkkuuden määrittely Jos haluat tulostaa tietoa liukulukumuodossa, voit määrittää pyöristystarkkuuden. Se on erityisen hyödyllistä valuutta-arvoilla työskenneltäessä. Tarkkuuden määrittäjä tulee sijoittaa juuri ennen tyypinmäärittäjää. Se koostuu pisteestä, jota seuraa pyöristyksessä käytettävä desimaalien määrä. Tämä määrittäjä käsittelee vain tietoa, joka tulostetaan 'f'-tyypinmäärittäjää käyttäen: printf( "%.2f", 5.333333 ); // tulostaa "5.33" C-kielessä on mahdollista käyttää tarkkuuden määrittäjää printf()- funktiossa desimaalitulostuksen etumerkkien määrä määrittämiseksi. Tarkkuuden määrittäjällä ei ole PHP4:ssä vaikutusta desimaalitulostukseen. Käytä etumerkkien määrittäjää etunollien lisäämiseksi kokonaislukuihin. Muunnosmäärittäjät: yhteenveto Taulukko 17.2 luettelee määrittäjät, jotka muodostavat muunnosmäärittelyn, siinä järjestyksessä, jossa ne on sijoitettava. Huomaa, että on vaikeaa käyttää sekä siirtymän määrittäjää että kentänleveysmäärittäjää. Sinun tuleekin valita, kumpaa käytät eri tilanteissa. Taulukko 17.2 Muunnosmäärittäjän osat Nimi Kuvaus Esimerkki Siirtymän määrittäjä Määrittää niiden merkkien ' 4' määrän, jotka tulostuksen tulee käyttää, sekä merkin, jota sijoitetaan eteen, jos tila ei muutoin tule täyteen Kentänleveyden Määrittää tilan, jota tulostuksessa '20' määrittäjä käytetään Tarkkuuden määrittäjä Määrittää desimaalien määrän, '.4' johon double pyöristetään Tyypin määrittäjä Määrittää tietotyypin, joka tulostetaan 'd' Listaus 17.2 käyttää printf()-funktiota tulostamaan luettelo tuotteista ja hinnoista. Listaus 17.2 Tuotteiden hintaluettelo muotoillaan printf()-funktiolla 1: <html> 2: <head> 3: <title>using printf() to format a list of product prices</title> 4: </head>
308 17. Merkkijonoilla työskentely 5: <body> 6: <?php 7: $products = Array( "Green armchair"=>"222.4", 8: "Candlestick"=>"4", 9: "Coffee table"=>80.6 10: ); 11: print "<pre>"; 12: printf("%-20s%23s\n", "Name", "Price"); 13: printf("%'-43s\n", ""); 14: foreach ( $products as $key=>$val ) 15: printf( "%-20s%20.2f\n", $key, $val ); 16: printf("</pre>"); 17:?> 18: </body> 19: </html> Ensiksi määrittelemme assosiatiivisen taulukon, joka sisältää tuotteiden nimiä ja hintoja. Tulostamme PREelementin, jotta selain tunnistaisi välilyönnit ja rivinvaihdot. Ensimmäinen printf()-kutsu määrittää seuraavan muotoilun ohjausmerkkijonon: "%-20s%23s\n" Ensimmäinen muunnosmääritys ("%-20s") asettaa kentänleveysmäärittäjäksi 20 merkkiä ja käyttää vasenta tasausta. Tyypin määrittäjä on 's', joka vastaa merkkijonoa. Toinen muunnosmääritys ("%23s") asettaa myös kentänleveyden ja käyttää oikean reunan tasausta. Tämä printf()-kutsu tulostaa kenttien otsikot. Toinen printf()-kutsu piirtää väliviivan, joka koostuu tavuviivasta ja sisältää 43 merkkiä. Saamme sen aikaan käyttämällä siirtymämäärittäjää, joka lisää siirtymän tyhjään merkkijonoon. Viimeinen printf()-kutsu on osa foreach-lausetta, joka käy silmukassa läpi tuotetaulukkomme. Siinä käytämme kahta muunnosmääritystä. Ensimmäinen ("%-20s") tulostaa tuotteen nimen käyttäen vasenta tasausta ja 20 merkin tulostusleveyttä. Toinen muunnosmääritys ("%20.2f") käyttää 20 merkin kentänleveyttä, oikean reunan tasausta ja kahden desimaalin pyöristystarkkuutta. Kuva 17.3 esittää listauksen 17.2 tulostuksen.
17. Merkkijonoilla työskentely 309 KUVA 17.3 Tuotteet ja hinnat muotoiltuina printf()-funktiolla. Muotoillun merkkijonon tallentaminen Yleensä printf() vain tulostaa tiedot selaimelle, emmekä pääse tutkimaan tuloksia skripteissä. Voimme kuitenkin käyttää funktiota sprintf(), joka toimii aivan samalla tavalla kuin printf(), paitsi että se palauttaa merkkijonon, jonka voit tallentaa muuttujaan myöhempää käyttöä varten. Seuraava koodi käyttää sprintf()-funktiota doublen pyöristämiseksi kahteen desimaaliin ja tuloksen sijoittamiseksi muuttujaan $dosh: $dosh = sprintf("%.2f", 2.334454); print "You have $dosh dollars to spend"; Varsinainen käyttötapa sprintf()-funktiolle on muotoillun tiedon kirjoittaminen tiedostoon. Voit kutsua sprintf()-funktiota ja sijoittaa sen palautusarvon muuttujaan, joka voidaan sitten tulostaa tiedostoon fputs()-funktiolla. Merkkijonojen tutkiminen Et aina tiedä kaikkea tiedosta, jota käsittelet. Merkkijonot voivat tulla monesta eri lähteestä: käyttäjän syöttötietoina, tietokannoista, tiedostoista ja Web-sivuilta. Ennen kuin alat työstää tietoa, joka tulee ulkoisesta lähteestä, on hyvä tietää kyseisestä tiedosta enemmän. PHP4 tarjoaa käyttöön monia funktioita, joilla voidaan ottaa selville tietoa merkkijonoista. Huomautus merkkijonojen indeksoinnista Käytämme toistuvasti sanaa indeksi merkkijonojen yhteydessä. Yleensä indeksi liittyy taulukoihin. Itse asiassa merkkijonot ja taulukot muistuttavat toisiaan: voit pitää merkkijonoja merkkitaulukkoina. Voit siis päästä käsiksi merkkijonon yksittäiseen merkkiin indeksiä käyttäen: $test = "scallywag"; print $test[0]; // tulostaa "s" print $test[2]; // tulostaa "a"
310 17. Merkkijonoilla työskentely Siksi on tärkeää muistaa, että samalla lailla kuin taulukoiden kohdalla, myös merkkijonojen kohdalla ensimmäinen indeksi on nolla. Merkkijonon pituuden selvittäminen strlen()-funktiolla Voit käyttää strlen()-funktiota määrittämään merkkijonon pituuden. Se ottaa argumenteikseen merkkijonon ja palauttaa kokonaisluvun, joka edustaa muuttujassa olevien merkkien määrää. Merkkijonon pituus tarkistetaan usein, kun käyttäjä syöttää tietoa, jota skriptin tulee käsitellä. Seuraava koodi testaa, onko membership-muuttujassa (joka sisältää jäsenkoodin) oleva merkkijono pituudeltaan 4 merkkiä: if ( strlen( $membership ) == 4 ) print "Thank you!"; else print "Your membership number must have 4 digits<p>"; Käyttäjää kiitetään hänen antamistaan tiedoista vain, jos globaali $membership-muuttuja sisältää nelä merkkiä, muutoin generoidaan virheilmoitus. Osamerkkijonon etsiminen strstr()-funktiolla Voit käyttää strstr()-funktiota tutkimaan, onko merkkijonossa sisällä toinen merkkijono. Funktio ottaa kaksi argumenttia: lähdemerkkijonon ja osamerkkijonon, joka halutaan löytää. Funktio palauttaa arvon false, jos osamerkkijonoa ei löydy. Muutoin funktio palauttaa sen osan lähdemerkkijonosta, joka alkaa osamerkkijonolla. Kuvittele, että haluamme käsitellä seuraavassa esimerkissä "AB"-alkuisia jäsenkoodeja eri tavalla kuin muita jäsenkoodeja: $membership = "pab7"; sif ( strstr( $membership, "AB" ) ) print "Thank you. Don't forget that your membership expires soon!"; else print "Thank you!"; Koska testimuuttujamme $membership sisältää merkkijonon "AB", strstr() palauttaa merkkijonon "AB7". Se vastaa totuusarvoa tosi, joten tulostamme erikoisviestin. Mitä tapahtuu, jos käyttäjä syöttää tekstin "pab7"? PHP tunnistaa isot ja pienet kirjaimet ja niin tekee myös strstr()-funktio, joten merkkijonoa "AB" ei löydy merkkijonosta. If-lauseen testi epäonnistuu ja oletusviesti tulostetaan selaimelle. Jos haluamme hakea joko "AB"-merkkijonoa tai "ab"-merkkijonoa, on meidän käytettävä stristr()-funktiota, joka toimii täsmälleen samalla tavalla kuin strstr(), paitsi että se ei erottele isoja ja pieniä kirjaimia.
17. Merkkijonoilla työskentely 311 Osamerkkijonon paikan löytäminen strpos()-funktiolla Funktio strpos() kertoo sekä sen, onko merkkijono sisällä isommassa merkkijonossa, että osamerkkijonon sijainnin. Funktio ottaa kaksi argumenttia: lähdemerkkijonon ja haettavan osamerkkijonon. Funktio voi ottaa vielä kolmannen valinnaisen argumentin, joka on kokonaisluku, joka edustaa hakemisen aloituskohtaa. Jos osamerkkijonoa ei ole olemassa, strpos() palauttaa arvon false. Muutoin se palauttaa kokonaisluvun, joka kertoo, mistä osamerkkijono alkaa. Seuraava koodi käyttää strpos()-funktiota takaamaan, että merkkijono alkaa merkkijonolla "mz": $membership = "mz00xyz"; if ( strpos($membership, "mz") === 0 ) print "hello mz"; Huomaa, että käytimme edellä pientä jekkua odotetun tuloksen saamiseksi. Funktio strpos() hakee merkkijonoa "mz" merkkijonostamme, mutta löytää sen heti merkkijonon alusta. Tällöin funktio siis palauttaa arvon nolla, joka on vertailussa sama kuin epätosi. Ratkaisemme ongelman käyttämällä PHP4:n uutta yhtäsuuruusoperaattoria, jossa on kolme yhtäsuuruusmerkkiä (===); tuo operaattori palauttaa arvon tosi, jos vasemmalla ja oikealla puolella olevat operandit ovat yhtäsuuria ja samaa tyyppiä. Merkkijonon osan sieppaaminen substr()-funktiolla Funktio substr() palauttaa merkkijonosta osan, joka määritetään alkuindeksin ja osan pituuden avulla. Funktio ottaa kaksi argumenttia, lähdemerkkijonon ja aloitusindeksin. Se palauttaa kaikki merkit alkaen alkuindeksistä merkkijonon loppuun. Funktio hyväksyy kolmannen, valinnaisen argumentin, joka on kokonaisluku ja edustaa palautettavan merkkijonon pituutta. Jos tuota argumenttia käytetään, substr() palauttaa vain halutun osan lähdemerkkijonosta aloitusindeksistä eteenpäin: $test = "scallywag"; print substr($test,6); // tulostaa "wag" print substr($test,6,2) // tulostaa "wa" Jos funktiolle viedään negatiivinen arvo toisena argumenttina (aloitusindeksi), se aloittaa laskennan lopusta. Seuraava koodi kirjoittaa tietyn viestin ihmisille, joiden lähettämät email-osoitteet päättyvät merkkijonoon ".uk". $test = "matt@corrosive.co.uk"; if ( $test = substr( $test, -3 ) == ".uk" ) print "Don't forget our special offers for British customers"; else print "Welcome to our shop!";
312 17. Merkkijonoilla työskentely Merkkijonon jäsentely strtok()-funktiolla Voit jäsennellä merkkijonon sana sanalta käyttämällä strtok()-funktiota. Se ottaa alustavasti kaksi argumenttia, lähdemerkkijonon ja erottimet, joita pilkkomisessa käytetään. Erotinmerkkijono voi sisältää halutun määrän merkkejä. Funktio palauttaa ensimmäisen sanan. Kun funktiota kutsutaan ensimmäistä kertaa, lähdemerkkijono laitetaan välimuistiin. Peräkkäisissä kutsuissa sinun tulee viedä strtok()-funktiolle pelkästään erotinmerkkijono. Funktio palauttaa seuraavan sanan jokaisen kutsun yhteydessä. Funktio palauttaa arvon epätosi, kun merkkijonon loppu on saavutettu. Funktiota kutsutaan yleensä toistuvasti silmukan sisällä. Listaus 17.3 käyttää strtok()-funktiota jäsentelemään URL-osoite; funktio erottelee isäntäosan ja polun kyselymerkkijonosta ja jakaa sitten kyselymerkkijonon nimi/arvo-pareihin. Kuva 17.3 esittää listauksen 17.3 tulostuksen. Listaus 17.3 Merkkijonon jakaminen osiin strtok()-funktiolla 1: <html> 2: <head> 3: <title>listing 17.3 Dividing a string into 4: tokens with strtok()</title> 5: </head> 6: <body> 7: <?php 8: $test = "http://www.deja.com/qs.xp? 9: OP=dnquery.xp&ST=MS&DBS=2&QRY=developer+php"; 10: $delims = "?&"; 11: $word = strtok( $test, $delims ); 12: while ( is_string( $word ) ) 13: { 14: if ( $word ) 15: print "$word<br>"; 16: $word = strtok( $delims); 17: } 18:?> 19: </body> 20: </html> Käyttämämme strtok()-funktio on hieman raaka työkalu ja vaatii muutamia temppuja toimiakseen jouhevammin. Ensiksi tallennamme erottimet muuttujaan $delims. Kutsumme sitten strtok()-funktiota käyttäen argumentteina URL-merkkijonoa ja $delims-erotinta. Tulos tallennetaan muuttujaan $word. While-
17. Merkkijonoilla työskentely 313 silmukan ehtolauseessa testaamme sitten, onko $word merkkijono. Jos se ei ole merkkijono, tiedämme, että merkkijonon loppu on saavutettu eikä muita toimintoja enää vaadita. Testaamme palautustyypin, koska merkkijono, joka sisältää kaksi erotinta rivillä, saisi strtok()-funktion palauttamaan tyhjän merkkijonon, kun se saavuttaa ensimmäisen näistä erottimista. Niinpä seuraavanlainen perinteinen testi while ( $word ) { $word = strtok( $delims ); } ei toimisi, koska $word sisältää tyhjän merkkijonon, vaikka lähdemerkkijonon loppua ei vielä olekaan saavutettu. Kun olemme varmistaneet, että $word sisältää merkkijonon, voimme siirtyä eteenpäin työskentelemään sillä. Jos $word ei sisällä tyhjää merkkijonoa, tulostamme sen selaimelle. Sitten meidän tulee kutsua strtok()- funktiota uudelleen täyttämään $word seuraavaa testiä varten. Huomaa, että emme vie lähdemerkkijonoa strtok()-funktiolle toista kertaa. Jos teemme niin, palautuu ensimmäinen sana uudelleen tutkittavaksi ja joudumme ikuiseen silmukkaan. Merkkijonojen muokkaaminen PHP4 tarjoaa käyttöön useita funktioita, joilla merkkijonoargumenttia voidaan manipuloida eri tavoin. Merkkijonon puhdistaminen trim()- ja ltrim()-funktioilla Kun teksti on saatu käyttäjältä tai tiedostosta, on hyvä varmistaa, että merkkijonoissa ei ole ylimääräisiä välilyöntejä tai muita 'white space' -merkkejä. Yleensä ylimääräisiä välilyöntejä tulee merkkijonon alkuun tai loppuun. Funktio trim() poistaa kaikki ylimääräiset 'white space' -merkit (rivinvaihto, sarkainpainallukset, välilyönnit) sekä merkkijonon alusta että lopusta. Se ottaa argumentikseen muokattavan merkkijonon ja palauttaa puhdistetun version. $text = "\t\t\tlots of room to breath "; $text = trim( $text ); print $text; // tulostaa "lots of room to breath"; Joskus haluat ehkä säilyttää merkkijonon alun tyhjät merkit. Siinä tapauksessa voit käyttää PHP:n chop()- funktiota, joka toimii aivan samoin kuin trim(), mutta poistaa vain merkkijonon lopussa olevat 'white space' -merkit: $text = "\t\t\tlots of room to breath ";
314 17. Merkkijonoilla työskentely $text = chop( $text ); print $test; // tulostaa " lots of room to breath"; PHP tarjoaa vielä käyttöön ltrim()-funktion, joka poistaa 'white space' -merkit vain merkkijonon alusta. Sekin palauttaa puhdistetun merkkijonon: $text = "\t\t\tlots of room to breath "; $text = ltrim( $text ); print $test; // tulostaa "lots of room to breath "; Merkkijonon osan muuttaminen substr_replace()-funktiolla Tämä substr_replace()-funktio toimii samalla lailla kuin substr(), paitsi että se sallii sinun korvata haluttu osamerkkijono toisella osamerkkijonolla. Funktio ottaa kolme argumenttia: muokattavan merkkijonon, lisättävän tekstin ja aloitusindeksin. Se hyväksyy myös valinnaisen argumentin, pituuden. Funktio etsii merkkijonosta osan, joka määritetään alkuindeksin ja pituuden avulla ja korvaa tuon osan argumenttina annetulla merkkijonolla. Funktio palauttaa muokatun merkkijonon. Seuraava koodi muokkaa jäsenkoodia: <? $membership = "mz99xyz"; $membership = substr_replace( $membership, "00", 2, 2 ); print "New membership number: $membership<p>"; // tulostaa "New membership number: mz00xyz"?> Osamerkkijonon korvaaminen str_replace()-funktiolla str_replace()-funktio muuttaa kaikki merkkijonoesiintymät toisesta merkkijonosta. Se ottaa kolme argumenttia: haettavan osamerkkijonon, korvaavan osamerkkijonon ja kohdemerkkijonon. Funktio palauttaa muutetun merkkijonon. Seuraava esimerkki käyttää str_replace()-funktiota muuttamaan kaikki merkkijonon "1999" esiintymät muotoon "2000": $string = "Site contents copyright 1999. "; $string.= "The 1999 Guide to All Things Good in Europe"; print str_replace("1999","2000",$string);
17. Merkkijonoilla työskentely 315 Isot ja pienet kirjaimet PHP sisältää useita funktioita, joilla voidaan muuntaa kirjaimet isoiksi tai pieniksi. Kun kirjoitat käyttäjän lähettämää tietoa tiedostoon tai tietokantaan, saatat haluta muuntaa sen kokonaan isoiksi kirjaimiksi tai kokonaan pieniksi kirjaimiksi ennen muita toimenpiteitä. Merkkijonon kirjaimet muunnetaan isoiksi funktiolla strtoupper(). Se ottaa argumentikseen muunnettavan merkkijonon ja palauttaa muunnetun merkkijonon: $membership = "mz00xyz"; $membership = strtoupper( $membership ); print "$membership<p>"; // tulostaa "MZ00XYZ" Merkkijonon merkit muunnetaan pieniksi kirjaimiksi funktiolla strtolower(). Sekin ottaa argumentikseen muunnettavan merkkijonon ja palauttaa muunnetun version: $home_url = "WWW.CORROSIVE.CO.UK"; $home_url = strtolower( $home_url ); if (! ( strpos ( $home_url, "http://" ) === 0 ) ) $home_url = "http://$home_url"; print $home_url; // tulostaa "http://www.corrosive.co.uk" PHP tarjoaa käyttöön myös etukirjainta koskevan funktion: ucwords() muuntaa merkkijonon ensimmäisen kirjaimen isoksi. Seuraavassa koodissa muunnetaan käyttäjän lähettämän nimitiedon ensimmäinen kirjain isoksi: $full_name = "violet elizabeth bott"; $full_name = ucwords( $full_name ); print $full_name; // tulostaa "Violet Elizabeth Bott" Vaikka tämä funktio muuntaakin ensimmäisen kirjaimen isoksi, se ei koske muita kirjaimia. Jos olet epävarma muista kirjaimista (tulos on esimerkiksi VIolEt elizabeth bott), voit aina tehdä muunnoksen koko merkkijonolle. Onneksi PHP4 tarjoaa vielä käyttöön funktion ucwords(), joka osaa muuntaa merkkijonon jokaisen erillisen sanan ensimmäisen kirjaimen isoksi: $full_name = "VIolEt elizabeth bott"; $full_name = ucwords( strtolower($full_name) ); print $full_name; // tulostaa "Violet Elizabeth Bott"
316 17. Merkkijonoilla työskentely Merkkijonon pilkkominen taulukoiksi explode()-funktiolla Ihastuttavasti nimetty explode() toimii samalla lailla kuin strtok(). Se jakaa kuitenkin merkkijonon taulukoksi, jota voidaan sitten vaikkapa lajitella ja tutkia. Funktio ottaa kaksi argumenttia: erotinmerkkijonon, jonka avulla sanojen erottelu tapahtuu, ja itse lähdemerkkijonon. Erotinmerkkijonossa voi olla enemmän kuin yksi kirjain; merkit muodostavat yhden erotinmerkkijonon (strtok() sen sijaan käytti erotinmerkkijonon yksittäisiä merkkejä erillisinä erottimina). Seuraava koodi pilkkoo päivämäärän ja tallentaa tuloksen taulukkoon: $start_date = "2000-01-12"; $date_array = explode("-", $start_date); // $date[0] == "2000" // $date[1] == "01" // $date[2] == "12" Yhteenveto Merkkijonot ovat PHP:n peruskeino kommunikoida ulkoisen maailman kanssa ja tallentaa tietoa myöhempää käyttöä varten. Tällä tunnilla olet tutustunut muutamiin funktioihin, joilla voidaan käsitellä merkkijonoja skripteissä. Opit muotoilemaan merkkijonoja printf()- ja sprintf()-funktioilla. Sinun tulisi voida käyttää näitä funktioita sekä merkkijonojen luomiseen että tiedon muuntamiseen ja asettelemiseen. Opit myös tutkimaan merkkijonoja erikoisfunktioiden avulla ja muun muassa ottamaan selville merkkijonon pituuden strlen()- funktiolla, määrittämään osamerkkijonon esiintymisen strpos()-funktiolla ja ottamaan esille osamerkkijonon substr()-funktiolla. Luvun lopussa käsiteltiin merkkijonon perkaamista trim()-, ltrim()- ja chop()- funktioilla. Merkkijonon merkit opittiin muuntamaan isoiksi strtoupper()-funktiolla, pieniksi strtolower()- funktiolla; sanojen ensimmäiset merkit muunnettiin isoiksi ucwords()-funktiolla. Merkkijonon kaikki tietyn osamerkkijonon esiintymät voitiin muuttaa toisiksi str_replace()-funktiolla. Usko tai älä, mutta emme vielä ole lopettaneet merkkijonon käsittelyä kokonaan. PHP tarjoaa käyttöön säännöllisiä lausekkeita, joiden avulla merkkijonojen käsittely on funktioita tehokkaampaa. Säännöllisiä lausekkeita tutkimme seuraavassa luvussa. K&V K Onko olemassa vielä muita hyödyllisiä merkkijonofunktioita? V Kyllä. PHP4 sisältää noin 60 merkkijonofunktiota! Voit lukea niistä kaikista PHP4:n online-manuaaleista osoitteesta http://www.php.net/manual/ref.strings.php. K Esimerkissä, jossa esiteltiin printf()-funktion käyttöä, näytimme, kuinka rivinvaihtoja voitiin tehdä <PRE>tagin avulla. Onko tämä paras keino esittää muotoiltua tekstiä selaimella? V
17. Merkkijonoilla työskentely 317 Kyllä <PRE>-tagit ovat hyödyllisiä, jos haluat säilyttää puhtaan tekstin muotoilun HTML-sivullasi. Jos haluat tulostaa koko tekstiasiakirjan selaimellesi, on parasta antaa selaimen esittää koko teksti puhtaana tekstinä. Se voidaan toteuttaa header()-funktion avulla: Header("Content-Type: Text/Plain"); 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ä muunnosmäärittäjää käyttäisit printf()-funktion yhteydessä muotoillaksesi kokonaisluvun desimaaliluvuksi? Kirjoita koko syntaksi, kun kokonaislukuna on 33. 2. Kuinka siirtäisit edellisen kysymyksen muunnoksen siten, että tulostuksen eteen tulee tarvittava määrä nollia, jotta desimaaliosa olisi neljä merkkiä? 3. Kuinka määrittäisit kahden desimaalin tarkkuuden edellisten kysymysten liukuluvulle? 4. Millä funktiolla määrittäisit merkkijonon pituuden? 5. Millä funktiolla saat esille jonkin osamerkkijonon esiintymän aloituskohdan? 6. Millä funktiolla saat esille jonkin osamerkkijonon merkkijonosta? 7. Kuinka voit poistaa tyhjät merkit merkkijonon alusta? 8. Kuinka muuttaisit merkkijonon kirjaimet isoiksi kirjaimiksi? 9. Kuinka jakaisit merkkijonon osiin, jotka sijoitetaan sitten taulukkoon? Toiminta 1. Luo palautelomake, johon voidaan syöttää käyttäjän koko nimi ja email-osoite. Käytä kirjainten muuntamisfunktioita muuntaaksesi nimien ensimmäiset kirjaimet isoiksi. Tulosta sitten lomakkeen tiedot selaimelle. Tarkista, että käyttäjän email-osoite sisältää @-symbolin. Jos symbolia ei löydy, ohjelma varoituksen. 2. Luo desimaalilukuja (double) ja kokonaislukuja sisältävä taulukko. Käy läpi taulukko silmukassa ja muunna jokainen alkio liukuluvuksi, jossa on kaksi desimaalia. Käytä tulostuksessa oikean reunan tasausta ja 20 merkin kentänleveyttä.
318 17. Merkkijonoilla työskentely