Kirjautuminen

Haku

Tehtävät

Opasarkisto: JavaScript-perusopas: Osa 7 - Merkkijonojen käsittely

  1. Osa 1 - Perusteet
  2. Osa 2 - Muuttujat ja taulukot
  3. Osa 3 - Tapahtumankäsittelijät ja informaatioikkunat
  4. Osa 4 - Komentorakenteet
  5. Osa 5 - Funktiot
  6. Osa 6 - Lomakkeiden käsittely
  7. Osa 7 - Merkkijonojen käsittely
  8. Osa 8 - Ominaisuudet
  9. Osa 9 - Matemaattiset laskutoimitukset
  10. Osa 10 - Olio-ohjelmointi
  11. Osa 11 - Käytännön sovelluksia

Kirjoittaja: MikaBug. Vuosi: 2007.

Huomio! Tämä opas on vanhentunut. Oppaan sisältöön ei voi enää luottaa. Opas on säilytetty vain sen historiallisen arvon vuoksi.

Merkkijonojen käsittely on monien ohjelmointikielien yleisimpiä asioita. Merkkijono on pitempi tai lyhyempi pätkä tekstiä, esimerkiksi "JavaScript-kielellä voidaan ohjelmoida www-sivuille interaktiivisia toimintoja" on merkkijono, aivan samoin kuin on "a". Toisinaan merkkijonoista käytetään englanninkielistä nimitystä string.

Kuten aiemmin on jo käynyt ilmi, merkkijonoja voi yhdistellä plus (+)- operaattorilla, esimerkiksi document.write("Esi" + "merkki");. Merkkijonoja vertaillaan vastaavalla tavalla kuin lukuja, esimerkiksi "mika" != "heikki".

Merkkijonoja käsitellään JavaScriptissä String-olion kautta. String-oliolla on useita metodeja, joiden avulla voidaan esimerkiksi etsiä merkkijonosta tietyn merkin tai merkkien esiintymiä. Ominaisuuksia on vain yksi, length, joka kertoo merkkijonon pituuden:

var merkkijono = "Kivaa tämä JavaScript!";

var pituus = merkkijono.length;

Saman voi tehdä myös näin:

var pituus = "Kivaa tämä JavaScript!".length;

Seuraavaksi käydään läpi joitakin merkkijonojen käsittelyssä käytettäviä metodeja.

toUpperCase ja toLowerCase

Kirjainten muuttaminen pienistä isoiksi tapahtuu toUpperCase-metodilla. Vastaavasti kirjainten muuttaminen isoista pieniksi onnistuu metodilla toLowerCase.

var merkkijono = "JavaScript";
merkkijono = merkkijono.toUpperCase();		// JAVASCRIPT

var merkkijono2 = "JAVASCRIPT";
merkkijono2 = merkkijono2.toLowerCase();	// javascript

bold ja italics

Merkkijonon lihavointi tapahtuu bold-metodilla. Kirjainten kursivointi puolestaan onnistuu italics-metodilla. Metodit lisäävät merkkijonon alkuun ja loppuun HTML-kielen mukaiset tagit (<b></b>, <i></i>).

var merkkijono = "Tekstiä lihavoituna";
document.write(merkkijono.bold());

var merkkijono2 = "Tekstiä kursiivilla";
document.write(merkkijono2.italics());

link-metodilla voidaan merkkijonosta tehdä hyperlinkki parametrina annettavaan osoitteeseen. Metodi lisää merkkijonon alkuun ja loppuun HTML-kielen mukaiset tagit (<a href = "osoite"></a>).

var linkin_nimi = "Ohjelmointiputkaan";

document.write(linkin_nimi.link("http://www.ohjelmointiputka.net"));

sub ja sup

Muuttaa merkkijonon yläindeksiksi (sup) tai alaindeksiksi (sub). Metodit lisäävät merkkijonon alkuun ja loppuun HTML-kielen mukaiset tagit (<sub></sub>, <sup></sup>).

document.write("Veden kemiallinen tunnus on H" + "2".sub() + "O");

document.write("Asunnon koko on 58 m" + "2".sup());

replace

Tietyn merkin tai merkkijonon korvaaminen kohdemerkkijonosta onnistuu replace-metodilla. Metodille viedään kaksi parametria, joista ensimmäinen on korvattava merkki tai merkkijono, ja toinen korvaava merkki tai merkkijono. Seuraavassa skriptissä on toteutettu yksinkertainen etsi-korvaa-toiminto. Sivulla on isompi tekstilaatikko, johon käyttäjä voi kirjoittaa tekstiä. Lisäksi sivulla on kaksi tekstikenttää, joihin käyttäjä antaa korvattavan ja korvaavan merkkijonon. Korvaus kohdistuu tekstilaatikon sisältöön.

<html>

<head>

<title>Etsi ja korvaa</title>

<script type="text/javascript">

function Korvaa()
{
	var teksti = document.korvaa.teksti.value;
	var korvattava = document.korvaa.korvattava.value;
	var korvaava = document.korvaa.korvaava.value;

	teksti = teksti.replace(korvattava, korvaava);

	document.korvaa.teksti.value = teksti;
}

</script>

</head>

<body>

<form name="korvaa">

	<textarea cols="40" rows="10" name="teksti"></textarea>

	<br>

	<b>Korvattava<b><br>
		<input type="text" size="15" name="korvattava">

	<br>

	<b>Korvaava</b><br>
		<input type="text" size="15" name="korvaava">

	<input type="button" value="Korvaa" onclick="Korvaa()">

</form>

</body>

</html>

Skriptin ainoa uusi asia on replace-metodin käyttö. Metodille viedään ensimmäisenä parametrina korvattava-kentästä saatu arvo ja toisena parametrina korvaava-kentästä saatu arvo. Tekstilaatikon sisältö on sijoitettu teksti-muuttujaan, johon kohdistetaan korvaustoiminto lauseella teksti.replace(korvattava, korvaava). Metodi korvaa ensimmäisen haettavan merkin tai merkkijonon esiintymän, eli jos esiintymiä on useampia, on metodia kutsuttava uudelleen, kunnes kaikki esiintymät on korvattu. Jäljellä olevien esiintymien selvittämiseen voidaan käyttää myöhempänä esiteltävää indexOf-metodia.

charAt

Merkkijonoissa merkkeihin viitataan indeksin avulla. Ensimmäisen merkin indeksi on 0, toisen merkin 1 jne. charAt-metodilla voidaan hakea merkki parametrina annettavan indeksin kohdalta ja vaikkapa sijoittaa se muuttujaan.

var merkkijono = "JavaScript";
var merkki = merkkijono.charAt(3);	// merkki = a

indexOf ja lastIndexOf

Metodilla indexOf voidaan etsiä merkkijonosta tiettyä merkkiä tai merkkijonoa. Metodille voidaan viedä kaksi parametria, joista ensimmäinen parametri on etsittävä merkki tai merkkijono ja toinen vaihtoehtoinen parametri määrittää, monennenko esiintymän metodi etsii. Jos merkkijono löytyy, metodi palauttaa merkkijonon ensimmäisen merkin indeksin. Jos merkkijonoa ei löydy, se palauttaa arvon -1.

Metodi lastIndexOf toimii muuten samalla tavalla kuin edellinen metodi, mutta se aloittaa haettavan merkkijonon etsimisen merkkijonon lopusta.

Seuraava esimerkki valottanee metodien eroja:

var merkkijono = "JavaScript Java";

// indexOf-metodi palauttaa arvon 1:
var indeksi_1 = merkkijono.indexOf("ava");

// lastIndexOf-metodi palauttaa arvon 12:
var indeksi_2 = merkkijono.lastIndexOf("ava");

Metodi indexOf aloittaa merkkijonon "ava" etsimisen merkkijonon "JavaScript Java" alusta. Koska toista parametria ei ole annettu, se etsii ensimmäisen esiintymän. Tässä tapauksessa esiintymän ensimmäisen merkin indeksi on siis 1 (JavaScript Java). Sen sijaan metodi lastIndexOf aloittaa samaisen merkkijonon etsimisen lopusta päin, jolloin se törmää toiseen "ava"-merkkijonoon ja palauttaa tämän merkkijonon ensimmäisen merkin indeksin 12 (JavaScript Java).

Jos indexOf-metodille olisi annettu toisena parametrina luku 2, se olisi palauttanut saman indeksin kuin lastIndexOf-metodi, koska se olisi hypännyt ensimmäisen esiintymän yli.

Seuraavaksi esimerkki, jossa etsitään merkkijonoa, ja riippuen löytyykö sitä, näytetään viesti-ikkunassa vastaava teksti.

var teksti = "Nyt osataan jo joitakin String-metodeja";

var haettava = "ring";

var indeksi = teksti.indexOf(haettava);

if(indeksi != -1)
	alert("Merkkijono löytyi!");
else
	alert("Merkkijonoa ei löytynyt!");

substring

Metodi substring palauttaa merkkijonon parametreina annettujen indeksien väliltä.

var teksti = "Ohjelmoidaan JavaScriptiä";

var pala_tekstia = teksti.substring(3, 8);

alert(pala_tekstia);		// Tulostaa merkkijonon "elmoi"

Palautuvan merkkijonon ensimmäisen merkin "e" indeksi on 3 ja viimeisen merkin "i" indeksi on 7. Toinen parametri on siis yhtä isompi kuin viimeisen palautuvan merkin indeksi.

Yhdistämällä indexOf- ja lastIndexOf-metodien käytön substring-metodin käyttöön voidaan etsiä kahden tietynlaisen merkkijonon tai merkin välissä olevaa merkkijonoa.

Seuraavassa esimerkissä poimitaan osoitteesta www.ohjelmointiputka.net merkkijono "ohjelmointiputka" ja tulostetaan se näyttöön.

var osoite = "www.ohjelmointiputka.net";

var indeksi_1 = osoite.indexOf("www.");

var indeksi_2 = osoite.lastIndexOf(".net");

var teksti = osoite.substring(indeksi_1 + 4, indeksi_2);

document.write("Haettava teksti on " + teksti);

Huomaa, että indeksi_1-muuttujaan lisätään luku 4, koska indexOf-metodin palauttama arvo on merkkijonon "www." ensimmäisen merkin indeksi. Haluamme kuitenkin tietää pisteen (.) jälkeisen merkin indeksin, joten lisäys on tarpeen.

Kannattaa huomata, että funktio voi olla toisen funktion (tai tässä tapauksessa metodin) parametri:

var teksti = osoite.substring(osoite.indexOf("www.") + 4, osoite.lastIndexOf(".net"));

Tällaisten pienten seikkojen tietäminen vähentää tarvittavan koodin määrää. Toiminnaltaan hyvin pitkälle substring-metodin kaltainen metodi on substr, jolle viedään toisena parametrina lähdemerkkijonosta poimittavan merkkijonon pituus. Ensimmäinen parametri on substring-metodin tavoin poimittavan merkkijonon ensimmäisen merkin indeksi.

split

split-metodilla voidaan merkkijonosta poimia erotinmerkkien välissä olevat osamerkkijonot taulukkoon omiin soluihinsa. split-metodin ensimmäinen parametri on käytettävä erotinmerkki ja toinen vaihtoehtoinen parametri poimittavien osamerkkijonojen määrä.

var taulukko = new Array(3);
var merkkijono = "Eka|Toka|Kolmas";

taulukko = merkkijono.split("|", 3);	// taulukko[0] = "Eka", taulukko[1] = "Toka", taulukko[2] = "Kolmas"

alert(taulukko[2]);	// Näyttää viesti-ikkunassa merkkijonon "Kolmas"

Säännöllisten lausekkeiden käyttö

Tekstistä voi etsiä ja korvata tiettyjen sääntöjen mukaisia merkkijonoja käyttämällä JavaScriptin match- ja replace-metodeja. Tällöin puhutaan säännöllisistä lausekkeista, joita taitavasti käyttämällä pystytään merkkijonoihin kohdistamaan monimutkaisiakin toimenpiteitä vähällä koodimäärällä. Tässä oppaassa ei käsitellä tarkemmin säännöllisiä lausekkeita, koska Antti Laaksosen kirjoittama opas Säännölliset lausekkeet PHP:ssä käy hyvin oppimateriaaliksi myös JavaScriptin kanssa työskentelevälle. On kuitenkin huomattava, että JavaScriptissä säännöllistä lauseketta ei laiteta lainausmerkkien sisään eikä näin ollen erikoismerkkien eteen tule kahta kenoviivaa.

Merkkijonojen etsinnässä käytettävän match-metodin syntaksi on merkkijono.match(säännöllinen_lauseke); ja korvaamisessa käytettävän replace-metodin syntaksi merkkijono.replace(säännöllinen_lauseke, korvaava_merkkijono);. Mikäli säännöllisen lausekkeen mukaista merkkijonoa ei löydy, match-metodi palauttaa arvon null.

Seuraavaksi pari esimerkkiä match- ja replace-metodien käytöstä.

var merkkijono = "Säännöllisten lausekkeiden käyttöä.";

// Jos merkkijonosta löytyy sana "lausekkeiden", näytetään viesti:
if(merkkijono.match(/\blausekkeiden\b/)) { alert("Sana löytyi"); }

// Korvataan merkkijonosta sana "käyttöä" sanalla "opettelua":
alert(merkkijono.replace(/\bkäyttöä/, "opettelua"));

Metodit etsivät vain ensimmäisen vastaan tulevan säännöllisen lausekkeen mukaisen merkkijonon esiintymän. Mikäli teksti sisältää useampia esiintymiä, on käytettävä esimerkiksi while-silmukkaa kaikkien läpikäymiseksi.

Sähköpostiosoitteen tarkistaminen

Tämän oppaan lopuksi ohjelmoidaan skripti, joka tarkistaa käyttäjän antaman sähköpostiosoitteen kelvollisuuden. Sähköpostiosoitteelle on hyvin vaikeaa, tai oikeastaan mahdotonta, tehdä täysin luotettavaa tarkistusta ohjelmallisesti. Tästä syystä sähköpostiosoitteeseen tulisi aina lähettää varmistusviesti, joka vastaanottajan on jollakin tavalla kuitattava, ja tällä tavoin osoitettava, että on todellinen ihminen eikä esimerkiksi haittaohjelma.

<html>

<head>

<title>Sähköpostiosoitteen tarkistus</title>

<script type="text/javascript">

function TarkistaOsoite()
{
	// Sijoitetaan sähköpostiosoite lomakkeen kentästä muuttujaan:
	var osoite = document.lomake.maili.value;

	// Luodaan tila-muuttuja, joka edustaa osoitteen kelvollisuutta (1 = kelvollinen, 0 = kelvoton):
	var tila = 1;

	// Tarkistetaan ensin, onko kenttä tyhjä:
	if(osoite.length == 0)
		alert("Ole hyvä ja anna sähköpostiosoitteesi.");
	else
	{
		// Tarkistetaan, sisältääkö osoite @-merkkiä:
		if(osoite.indexOf("@") == -1)
			tila = 0;

		// Tarkistetaan, sisältääkö osoite useampaa @-merkkiä:
		if(osoite.indexOf("@") != osoite.lastIndexOf("@"))
			tila = 0;

		// Tutkitaan domain-päätteen kelvollisuus:
		var paate = osoite.substring(osoite.lastIndexOf(".") + 1, osoite.length);

		var paatteen_pituus = paate.length;

		if(paatteen_pituus < 2 || paatteen_pituus > 4)
			tila = 0;

		// Lopuksi käyttäjälle annetaan virheilmoitus tai lomake lähetetään tila-muuttujan arvon mukaan:
		if(tila)
			document.forms[0].submit();
		else
			alert("Sähköpostiosoite ei kelpaa!");
	}
}

</script>

</head>

<body>

<form name="lomake">
	<b>Sähköpostiosoite:</b><br>
	<input type="text" name="maili" size="30">
	<input type="button" value="Tarkista" onclick="TarkistaOsoite()">
</form>

</body>

</html>

Ensimmäisenä skriptissä haetaan osoite lomakkeen kentästä ja sijoitetaan se muuttujaan osoite. tila-muuttujaan on alustavasti sijoitettu arvo 1, mikä kuvaa tilannetta, jolloin annettu sähköpostiosoite on kelvollinen. Jos jokin tarkistuksista kuitenkin huomaa osoitteen olevan jollain tavalla viallinen, muuttuu tila-muuttujan arvo nollaksi. Tämän perusteella tehdään lopulta päätös, lähetetäänkö lomake vai annetaanko käyttäjälle huomautus kelvottomasta sähköpostiosoitteesta.

Ensimmäiseksi tarkistetaan, onko osoitekenttä jätetty tyhjäksi. Tämä tapahtuu selvittämällä osoite-muuttujaan sijoitetun merkkijonon pituus length-ominaisuudella. Mikäli pituus on nolla, on kenttä tyhjä ja käyttäjälle näytetään huomautus viesti-ikkunassa. Muuten suoritetaan else-haara eli lähdetään tutkimaan osoitteen kelvollisuutta.

@-merkin sisältyminen osoitteeseen tarkistetaan edellisestä oppaasta tutulla tavalla indexOf-metodia käyttäen. Mikäli osoitteesta ei löydy @-merkkiä, palauttaa metodi arvon -1, jolloin ehto on tosi. Tällöin tila-muuttujan arvoksi tulee 0.

Kahden tai useamman @-merkin sisältyminen osoitteeseen selviää indexOf- ja lastIndexOf-metodien yhteiskäytöllä. Molemmilla metodeilla etsitään @-merkkiä. indexOf-metodi aloittaa etsimisen osoitteen alusta, lastIndexOf lopusta. Mikäli @-merkkejä on osoitteessa vain yksi, molemmat metodit palauttavat saman indeksin. Jos osoitteessa on useampi @-merkki, indexOf-metodi palauttaa alusta lukien ensimmäisen @-merkin indeksin ja lastIndexOf-metodi lopusta lukien ensimmäisen @-merkin indeksin. Indeksit eivät siis ole tällöin samoja ja ehdosta tulee tosi, jolloin tila-muuttujan arvoksi tulee nolla.

Seuraavaksi tutkitaan domain-päätteen kelvollisuus. Osoitteen päätteen selvittämiseen käytetään substring-metodia, jolle annetaan parametreina päätteen ensimmäisen ja viimeisen merkin indeksi. Toinen parametri on sama kuin osoitteen pituus, joten se saadaan helposti selville length-ominaisuudella (muista, että substring-metodin toinen parametri on yhtä suurempi kuin viimeisen palautettavan merkin indeksi). Ensimmäisen merkin indeksi saadaan etsimällä viimeinen osoitteessa esiintyvä piste (.) ja lisäämällä tähän indeksiin 1.

Päätteen pituus selvitetään length-ominaisuudella ja saatu arvo sijoitetaan paatteen_pituus-muuttujaan. if-lauseella tutkitaan, onko pituus pienempi kuin kaksi tai suurempi kuin neljä. Jos on, pääte on kelvoton ja tila-muuttujan arvoksi tulee 0.

Viimeisenä skriptissä tehdään valinta tila-muuttujan perusteella. Jos muuttuja on 1 eli tosi, lomake lähetetään eteenpäin. Mikäli muuttuja on 0 eli epätosi, annetaan käyttäjälle ilmoitus kelvottomasta osoitteesta.

Yhteenveto

Tässä oppaassa kerrottiin muutama näppärä merkkijonojen käsittelyyn käytettävä metodi. Niitä on toki lisää, mutta näiden opiskelu jääköön jokaisen halukkaan itsensä tehtäväksi. Yleiseltä syntaksiltaan niiden käyttö on helppoa: var kasitelty_merkkijono = alkup_merkkijono.metodi([param_1]...[param_n]);. JavaScriptin kaikki metodit löytyvät Java2s-sivustolta, jossa on myös lista erityisesti merkkijonojen käsittelyyn tarkoitetuista String-olion metodeista. Seuraava opas kertoo JavaScriptin ominaisuuksista, joiden avulla pystyy muun muassa muuttamaan sivun taustaväriä ja selvittämään käytettävän selaimen nimen.


Kommentit

Meitzi [19.08.2007 23:09:52]

Lainaa #

Sähköpostiosoitteen oikeellisuuden tarkistaminen on yllättävän mielenkiintoinen juttu. Lisäksihän siitä voidaan tarkistaa, että ennen @ merkkiä on vähintään yksi merkki. Pisteitä ei saa olla kahta peräkkäin ja pisteen sekä @ merkin välissä pitää olla vähintään yksi merkki. Lisäksi voidaan tehdä merkkirajoitteita. Aikasemminhan vain eng(?) kirjaimet olivat mahdollisia, mutta nykyään myös ä ja ö ovat mahdollisia? Lienee edellen kuitenki rajoitteita erikoisimmista merkeistä. (,:;+- jne)

nörtti [02.09.2007 10:45:59]

Lainaa #

Olisi kiva jos jossainvälissä kerrotaisiin miten selaimen voi tunnistaa JavaScripillä.

MikaBug [02.09.2007 10:52:23]

Lainaa #

Selaimen tunnistus on tulossa seuraavassa oppaassa esimerkkien kera.

gamehouse [16.09.2007 13:57:49]

Lainaa #

Kuinka monta opasta aiot tehdä? (nyk. 7 osa - viim. ? osa)

MikaBug [16.09.2007 14:23:47]

Lainaa #

Oppaita tulee yhteensä 11, eli vielä neljä on julkaisematta. Uskoisin, että nämä neljä opasta julkaistaan parin kolmen seuraavan viikon aikana. Viimeisiin oppaisiin tulee mm. olio-ohjelmointia, käytännön sovelluksia (hiireen reagoivat painikkeet, animaatiot, kellonaika...), matemaattisia laskutoimituksia Math-olion avulla sekä käydään läpi hieman JavaScriptin ominaisuuksia.

jlaire [07.10.2007 12:30:42]

Lainaa #

lainaus:

Metodit etsivät vain ensimmäisen vastaan tulevan säännöllisen lausekkeen mukaisen merkkijonon esiintymän. Mikäli teksti sisältää useampia esiintymiä, on käytettävä esimerkiksi while-silmukkaa kaikkien läpikäymiseksi.

Kyllä JavaScript globaaleja hakuja tukee:

js> "abcdefghij".match(/./g)
a,b,c,d,e,f,g,h,i,j
js> "abcdefghij".replace(/(\w)(\w)/g, "$2$1 ")
ba dc fe hg ji

Ceox [21.11.2007 18:28:38]

Lainaa #

calc_value = document.form.field.value;
calc_value.replace([^0-9][^'+', '-', '*', '/'], "");

Miksi tuo ei toimi?
Tarkoituksena olisi siis korvata kaikki muut merkit paitsi 0-9 ja +, -, / sekä * tyhjällä.

jlaire [25.11.2007 16:06:52]

Lainaa #

Ceox kirjoitti:

calc_value = document.form.field.value;
calc_value.replace([^0-9][^'+', '-', '*', '/'], "");

Miksi tuo ei toimi?

Kannattaa kysellä tuolla keskustelussa, saa paljon nopeammin vastauksia.

Mutta siis, syntaksi on ihan pielessä... Lisäksi replace ei tee mitään muutoksia, pelkästään palauttaa muunnetun merkkijonon.

Tällä tavalla:

var field = document.form.field;
field.value = field.value.replace(/[^0-9+\-*\/]/g, "");

Kirjoita kommentti

Huomio! Kommentoi tässä ainoastaan tämän oppaan hyviä ja huonoja puolia. Älä kirjoita muita kysymyksiä tähän. Jos koodisi ei toimi tai tarvitset muuten vain apua ohjelmoinnissa, lähetä viesti keskusteluun.

Muista lukea kirjoitusohjeet.
Tietoa sivustosta