Andrise programmeerimisalane WIKI
Stringid ja tekstitöötlus
String on JavaScriptis andmetüüp teksti esitamiseks. Stringi (inglise keeles nöör) nimetus tuleb faktist, et stringiväärtuse koostab arvuti mälus üksteise järel olevatest baitidest, millest igaüks tähistab ühte tähte ja mis kokku moodustavadki omamoodi „baitide nööri“. Nagu numbridki, on ka tekst tegelikult objekt, pärides enda omadused Object.prototype prototüübilt.
Kõik JavaScripti stringid on unikood kodeeringus, hoolimata HTML lehel kasutataud kodeeringust. Juhul kui HTML leht on mõnes muus kodeeringus, muudab brauser JavaScripti jaoks teksti kodeeringu ära.
Stringi loomine
Stringiobjekti saab luua konstruktoriga String. Objekt sisaldab ühe omadusena stringiprimitiivi ning lisaks meetodeid selle stringiga opereerimiseks. Stringiprimitiivi saab luua ka literaalina lihtsalt jutumärke (") või apostroofe (') kasutades, kus nende märkide vahel asuv tekstiväärtus ongi string.
JavaScript võimaldab stringiobjekti meetodeid rakendada ka stringiliteraaliga loodud stringidel - sellisel juhul loob JavaScript stringiprimitiivi ümber uue ajutise stringiobjekti, käivitab soovitud meetodi, tagastab tulemuse ning kustutab lõpuks ajutise objekti. Sellel põhjusel ei ole ka mõtet väga String konstruktorit kasutada - JavaScript teeb vajaliku töö ise ära.
Jutumärkide vahel olev tekst kuulub interpretaatori poolsele töötlemisele (tagurpidi kaldkriipsule järgnevad sümbolid muudetakse nende õigele kujule), aga apostroofidega määratud tekst mitte (v.a. \\ ja \', millest viimane muudetakse tekstiliseks apostroofiks stringi lõpetatuks lugemise asemel).
Tagrupidi kaldkriipsuga muudetavad sümbolid on järgnevad
\0- ErisümbolNUL(\u0000)\b- Kaldkriips (\u0008)\t- Tabulatsioonisümbol, horisontaalne (\u0009)\n- Reavahetus (\u000A)\v- Tabulatsioonisümbol, horisontaalne (\u000B)\f- Lehevahetus (\u000C)\r- Tagasijooks (\u000D)\"- Jutumärk (\u0022)\'- Apostroof (\u0027)\\- Tagurpidi kaldkriips (\u005C)\xZZ- Latin-1 kodeeringus sümbol, kahe kuueteistkümnendsüsteemi numbrina\uZZZZ- UTF-8 kodeeringus sümbol, nelja kuueteistkümnendsüsteemi numbrina
Kõik muud sümbolid mis järgnevad tagurpidi kaldkriipsule, jäetakse muutmata. Näiteks \€ on sama mis €.
var tekst = new String("Mingi tekst"); var tekst = "Mingi tekst"; alert("Esimene rida\nTeine rida");
UTF-8
UTF on akronüüm sõnadest Unicode Transformation Format (Unicode teisendusvorming) ning termini taga olev number kaheksa tähendab kaheksat bitti (oktett). Kodeering on muutpikkusega, kasutades üht kuni nelja oktetti ning on optimeeritud ladina tähtedega märgistike esitamiseks. Esimesed 128 märgistiku positsiooni - milles asuvad ASCII sümbolid - esitatakse muutmatult, jäädes sellega ASCII märgistikuga täielikult ühilduvaks.
Kodeering
Erinevalt fikseeritud pikkusega kodeeringutest (näiteks UTF-16) hoiab UTF-8 ruumi kokku, kuna vaikimisi eeldatakse enamuse kasutusel olevaid sümboleid ladina tähtede hulka ning seega kulub sümbolite esitamiseks vaid üks bait UTF-16 kahe baidi vastu. Eesti keeles kasutavad kahte baiti vaid tähed ÕÄÖÜ ning susisevad ŠŽ - kõik teised sümbolid jäävad ühe baidi sisse.
Unicode sümbol kodeeritakse n järjestikuse baidina, kus esimese baidi m=n (välja arvatud ühebaidilise sümboli korral, kus m=0) kõrgemat bitti näitavad, mitu baiti on kasutusel, järgmine bitt on null, järgnevate baitide kaks kõrgemat bitti on 1 ja 0. Vabad bitid (tabelis b) kasutatakse sümboli Unicode'i numbri jaoks.
| Baidid | Kasutatavad bitid | Esitlusviis | Märkus |
|---|---|---|---|
| 1 | 7 | 0bbbbbbb | ASCII sümbolid A-Z, 0-9 jms. |
| 2 | 11 | 110bbbbb 10bbbbbb | Diakriitiliste märkidega sümbolid, sh. eesti täpitähed ning kirillitsa |
| 3 | 16 | 1110bbbb 10bbbbbb 10bbbbbb | Kõik muud sümbolid (v.a. erimärgid) |
| 4 | 21 | 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb | Erimärgid |
Tabel 3. UTF-8 baitide kasutamine
BOM
Tekstifailide esitamisel Unicode vormingus (UTF-8, UTF-16) peaks tekstiredaktori jaoks olema failis info kasutatava kodeeringu kohta. See saavutatakse läbi faili alguses oleva BOM'i (byte order mark) ehk baidijärjestuse märgiga. Kui tekstiredaktor avab faili ning leiab esimeselt neljalt baidilt BOM-i, oskab ta faili ka vastavalt esitada. UTF-8 BOM näiteks on esitataud kolme baidiga EF BB BF () - juhul kui see on tekstifaili alguses, peaks redaktor käsitlema seda faili UTF-8 vormingus.
Probleem BOM-idega kaasneb brauseris veebilehtede esitamisega. Näiteks osad brauserid ootavad veebilehelt esimese märgendina DOCTYPE deklaratsiooni. Juhul kui esimesed sümbolid pole aga mitte <DO vaid , ei hakka brauser dokumenditüübi deklaratsiooni rohkem otsima ning langeb ühilduvusrežiimi vanemate veebilehtedega ühilduvuse tagamiseks. Tulemuseks võib olla veebilehe katkine kujundus - ühilduvus vanemate veebilehtedega tähendab standardite vabakäelisemat kasutamist ning mõningate mittestandardsete praktikate lubamist.
Samuti kui BOM on mõne serveripoolse skripti (näiteks PHP) esimeseks märgendiks, ei saa skript reeglina seada HTTP päisesse täiendavaid kirjeid (Content-type: text/plain, Location: ZZZ jne), kuna päiste lisamise hetkeks on skript midagi juba väljastanud (skripti alguses olnud BOM-i), aga päist saab seada ainult enne igasugust väljastust.
Seega veebilehtedel UTF-8 kodeeringus teksti esitamiseks tuleks jätta BOM märgend failist üldse ära ning teatada brauserile õige kodeering läbi vastava meta sildi või HTTP päise.
Meta silt kodeeringu määramiseks:
<meta http-equiv="Content-Type" content="text/html; Charset=UTF-8" />
Kirje lisamine HTTP päisesse kodeeringu määramiseks (skriptimiskeeles PHP):
Header("Content-Type: text/html; Charset=UTF-8");
HTTP päise muutmine Apache serveris vaikimisi kodeeringu seadmisel (failis .htaccess või serveri konfiguratsioonifailis):
AddDefaultCharset utf-8
Lühidalt võib UTF-8 arendaja jaoks kokku võtta nii - tähemärki salvestatakse reeglina kas ühe (ladina tähed) või kahe (täpitähed) baidiga. JavaScripti poole peal ei olegi kodeeringu tuvastamisel väga vahet, kuna brauser hoolitseb ise tekstide ühtse kodeeringu eest. Küll aga peab hoolega jälgima sisendit serveri poolel. Näiteks JavaScriptiga ajaxi pärngut tehes ja encodeURIComponent funktsiooniga teksti serverile arusaadavale kujule viies saab server teksti alati UTF-8 vormingus, isegi kui leht mille ta ise välja saatis, oli Latin 1 (ISO-8859-1).
Stringi meetodid
Stringiobjektid saavad String.prototype objektilt kaasa terve hulga kasutatavaid meetodeid, mis aitavad teha mitmesugust tekstitöötlust. Stringide meetodeid saab rakendada nii stringiobjektidele, mis on loodud konstruktoriga String kui ka stringiliteraalidele. Näiteks on täiesti korrektne järgmine lause:
alert("mis kell on".substring(5,7)); // kel
Olemas on meetodid nii stringide liitmiseks (concat), regulaaravaldistega teksti kontrollimiseks (match) kui ka pärandmeetodid HTML koodi loomiseks (blink). Kuna veebilehte on tunduvalt mugavam töödelda läbi DOM objektide, siis HTML koodi loomise meetodeid praktiliselt enam ei kasutata. Pealegi ei vasta need ECMAScripti standardile.
Ükski stringi meetod ei muuda objekti stringi ennast, seda stringi kasutatakse ainult sisendiks - meetod väljastab tagastuskohta uue, vajadusel muudetud stringi.
charAt
String string.charAt(Number indeks)
Stringi meetod charAt tagastab stringist märgitud positsioonil asuva sümboli. Positsioonide arvestus algab numbriga 0 ning kui päritav positsioon ei asu vahemikus 0 .. string.length-1, on tagastusväärtuseks tühi string "".
alert("tere".charAt(0)); // t alert("tere".charAt(1)); // e alert("tere".charAt(2)); // r alert("tere".charAt(3)); // e
charCodeAt
Number string.charCodeAt(Number indeks)
Meetod tagastab soovitud positsioonil asuva sümboli unikoodi tähemärgi koodi numbrilise väärtuse, mis jääb vahemikku 0 .. 65535.
alert("tere".charCodeAt(1)); // 101 ("e")
concat
String string.contact(String parameetrid)
Meetod liidab parameetrid (mida võib olla üks või mitu) stringi enda väärtusele ja tagastab niiviisi saadud uue stringi. Stringiobjekti enda väärtus jääb samaks.
alert("tere".concat(" ", "maailm")); // tere maailm
fromCharCode
String String.fromCharCode(Number parameetrid)
fromCharCode meetod koostab uue stringi parameetrina saadud unikoodi tähetabeli numbrilistest väärtustest. Tegu on staatilise meetodiga, mis tegelikult kuulub konstruktori String juurde.
var tekst = String.fromCharCode(116, 101, 114, 101); //tere
indexOf
Number string.indexOf(String otsing)
Meetod indexOf on mõeldud otsinguks stringis olevast tekstist. Meetod võtab sisendiks otsinguteksti ning valikulise täiendava parameetrina ka positsiooni, millest alates otsingut teostatama hakatakse. Juhul kui otsitav on tekstis olemas, tagastatakse otsitava asukoha algus. Juhul kui midagi ei leita, on tagastusväärtuseks -1.
var tekst = "Siin on mingi rida teksti"; alert(tekst.indexOf("in")); // 2 alert(tekst.indexOf("ei ole")); // -1
lastIndexOf
Number string.lastIndexOf(String otsing)
lastIndexOf otsib sarnaselt meetodiga indexOf tekstist etteantud väärtuse positsiooni, kuid kui meetod indexOf teostab otsingut alustades alguses, siis lastIndexOf teeb sedasama alustades teksti lõpust.
var tekst = "Siin on mingi rida teksti"; alert(tekst.indexOf("in")); // 9
length
Number string.length
Omadus length on kirjutuskaitstud numbriline väärtus, mis sisaldab endas valitud stringis olevate sümbolite arvu.
alert("tekst".length); // 5
localeCompare
Number string.localCompare(String võrreldav1, String võrreldav2)
Meetod võrdleb stringiobjekti parameetriks saadud stringiga ja tagastab positiivse väärtuse, kui parameetrina saadud string on tähestiku järgselt eespool ning negatiivse, kui see paikneb tagapool. Meetod arvestab sümbolite võrdlemisel hetkel aktiivset lokaali. Teoreetiliselt peaks sellisel juhul Eesti arvutites asuma sümbol õ peale sümbolit v, kuid kahjuks ei saa sellele järjestusele kindel olla, kuna arvutitel on harva lokaal korrektselt seatud või pole arvutis Eesti lokaali seadmine võimalikki.
var t2hed = ['a','b','c','t','u','v','õ','ä','ö','ü']; t2hed.sort(function(a,b){ return a.localeCompare(b) });
match
mixed string.match(RegExp re)
match kontrollib objekti stringi parameetrina saadud regulaaravaldise vastu ning tagastab vaste leidmise korral esimese vaste, kui regulaaravaldises on parameeter g seadmata ning kõik vasted ühise massiivina, kui g on seatud.
var tekst = "4 tomatit, 5 kurki"; alert(tekst.match(/[0-9]/g)); // [4,5]
Regulaaravalidste kohta saab täpsemalt lugeda regulaaravaldiste peatükist.
replace
String string.replace(RegExp otsing, mixed asendus)
Meetod replace asendab objekti stringis sisendina saadud esimese parameetri regulaaravaldisele vastavad kohad teises parameetris oleva väärtusega. Kui regulaaravaldise omadus g on seatud, asendatakse kõik regulaaravaldisele vastavad tekstiosad, vastasel korral asendatakse vaid esimene vaste.
Asendatav tekst võib sisaldada mitmeid muutujaid, mis saavad oma väärtuse regulaaravaldiselt.
| Sümbolid | Asendus |
|---|---|
$1, $2, …, $99 | tekst mis sisaldus regulaaravaldises 1-99. sulgudes asuvas alamlauses |
$& | tekst stringis, mis vastas regulaaravaldisele |
$` | Tekst, mis jääb regulaaravaldisele vastavast tekstiosast vasakule |
$' | Tekst, mis jääb regulaaravaldisele vastavast tekstiosast paremale |
$$ | Dollarisümbol ($) |
var tekst = "3 tomatit ja 67 kurki"; alert(tekst.replace(/([0-9]+)/g,"[$1]"));
Näites lisame kõikidele tekstis esinevatele numbritele ümber kandilised sulud, nii et väljundiks on
[3] tomatit ja [67] kurki
Asendajaks võib olla ka funktsioon. Funktsiooni esimene parameeter sisaldab endas kogu regulaaravaldise vastet, teine aga ainult otsitavat (sulgudes olevat). Funktsiooni tagastusväärtus saabki asendajaks.
"abcdef".replace(/b(.*?)e/,function(kõik,otsitav){ return "b-" + otsitav + "-e"; }); // ab-cd-ef
Näide asendab stringis b..e funktsiooni poolt tagastatava väärtusega
search
Number string.search(RegExp re)
search otsib stringist regulaaravaldisele vastavat teksti ning tagastab sarnaselt meetodile indexOf vaste korral vaste alguse positsiooni. Kui midagi ei leita, on tagastusväärtuseks -1. Erinevalt meetoditest match ja replace ei arvesta search regulaaravaldise omadust g.
var tekst = "2 kurki ja 4 tomatit"; alert(tekst.search(/[3-9]/)); // 11
Näites otsime numbrit mis on vahemikus 3 kuni 9.
slice
String string.slice(Number algus[, Number lõpp])
Meetod slice väljastab uue stringi, mille sisuks on originaalse teksti osa alates esimese parameetriga märgitud positsioonist teise parameetriga (juhul kui on seatud - vastasel korral kuni stringi lõpuni) märgitud positsioonini.
Kui algust tähistav parameeter on negatiivse väärtusega, arvestatakse algust loendades stringi lõpust.
"tere maailm".slice(2,5); // "re ma" "tere maailm".slice(-3); // "ilm"
split
Array string.split(mixed eraldaja[, Number elemente])
Meetod split jagab stringi sisendiks saadud parameetri järgi osadeks ning tagastab need osad ühise massiivina. Parameetriks võib olla nii string kui regulaaravaldis.
var tekst = "a|b|c|d|e|f"; tekst.split("|"); // ["a","b","c","d","e","f"] var lause = "turul müüakse tomateid ja kurke"; alert(lause.split(/\s+/).length); // 5
Meetodil on ka teine, valikuline parameeter, mis määrab maksimaalse massiivi elementide arvu - juhul kui elementide arv ületab antud parameetris määratud väärtust, lõigatakse ülejäävad elemendid ära.
var tekst = "a|b|c|d|e|f"; tekst.split("|", 3); // ["a", "b", "c"]
substr
String string.substr(Number algus[, Number pikkus])
substr tagastab sarnaselt meetodile slice uue stringina valitud osa stringiobjektist. Meetodi esimene parameeter määrab tagastuse alguse positsiooni algses stringis ning teine parameeter määrab tagastatava stringi pikkuse. Juhul kui positsiooni väärtus on negatiivne, hakatakse lugemist arvestama tagurpidi stringi lõpust. Kui pikkuse parameeter on puudu, kaasatakse terve string alates alguse positsioonist.
var tekst = "turul müüakse tomateid ja kurke"; alert(tekst.substr(-13, 7)); // "teid ja"
substring
String string.substring(Number algus[, Number lõpp])
Meetod substring tagastab sarnaselt meetoditele substr ning slice määratud osa (algus .. lõpp-1) stringist uue stringina. Sisendparameetriteks on alguse postitsioon ning lõpu positsioon, kuid erinevalt meetodist slice, ei saa asukoha märkimiseks kasutada negatiivseid numbreid - negatiivne number teisendatakse nulliks. Kui teiseks parameetriks antud number on esimesest väiksem, vahetatakse parameetrite tähendused ära - esimene hakkab tähistama lõppu ja teine algust.
var tekst = "abcdefghij"; tekst.substring(2,5); // cde tekst.substring(5); // fghij tekst.substring(5,0); // abcde
toLocaleLowerCase
String string.toLocaleLowerCase()
Teisendab tekstis olevad suurtähed väiketähtedeks arvestades arvutis määratud lokaali. Enamuste keelte puhul on meetodi tulemus täpselt sama, mis meetodil toLowerCase. Erandiks on näiteks Türgi keel, mille tähestikus on olemas ilma täpita i. Sellisel juhul kui muuta suurtähte I (suur i täht) väiketäheks, ei ole tulemus mitte väike i, vaid unikood sümbol ı (\u0131). Eesti keele korral sarnaseid erandeid pole.
toLocaleUpperCase
String string.toLocaleUpperCase()
Teisendab tekstis olevad väiketähed suurtähtedeks arvestades arvutis määratud lokaali. Nagu meetodi toLocaleLowerCase korral, jääb enamuste keelte puhul meetodi tulemus täpselt samaks, mis meetodil toUpperCase. Kui Türgi lokaali korral muuta väiketähte i suurtäheks, on tulemuseks suure I asemel unikood sümbol İ (\u0130). Eesti keele korral sarnaseid erandeid pole.
toLowerCase
String string.toLowerCase()
Meetod toLowerCase teisendab kõik stringis olevad suurtähed väiketähtedeks ja tagastab tulemuse uue stringina.
var tekst = "Siin On Mõned Suurtähed"; alert(tekst.toLowerCase()); //siin on mõned suurtähed
toString
String string.toString()
Meetod toString väljastab stringiobjektis oleva primitiivstringi.
var tekst = new String("siin on tekst"); alert(tekst.toString()); // siin on tekst
toUpperCase
String string.toUpperCase()
Meetod toUpperCase teisendab kõik stringis olevad väiketähed suurtähtedeks ja tagastab tulemuse uue stringina.
var tekst = "väiketähed"; alert(tekst.toUpperCase()); //VÄIKETÄHED
valueOf
String string.valueOf()
Meetod väljastab stringiobjektis oleva primitiivstringi. Identne meetodiga toString.
Mittestandardsed meetodid
JavaScripti versioonis 1.5 puuduvad mõned stringide meetodid, mis võivad tihtipeale siiski kasulikuks osutuda. Üheks selleks võiks näiteks olla trim, mille ülesandeks oleks eemaldada stringi servadest mittevajalikud sümbolid (näiteks tühikud jms.).
Järgnevas näites laiendame stringi prototüüpi String.prototype lisades sinna vajalikud meetodid, peale mida on võimalik kasutada deklareeritud meetodeid kõikidel JavaScripti stringidel.
/** * Eemaldab stringis vasakus servas asuvad ettemääratud sümbolid * @param {String} chars Kustutatavad sümbolid (või tühik, kui seadmata) * @return tagastab uue stringi */ String.prototype.ltrim = function(chars){ return this.replace(new RegExp("^["+(chars || "\\s")+"]+", "g"),''); } /** * Eemaldab stringis paremas servas asuvad ettemääratud sümbolid * @param {String} chars Kustutatavad sümbolid (või tühik, kui seadmata) * @return tagastab uue stringi */ String.prototype.rtrim = function(chars){ return this.replace(new RegExp("["+(chars || "\\s")+"]+$", "g"),''); } /** * Eemaldab stringis vasakus ja paremas servas asuvad ettemääratud sümbolid * @param {String} chars Kustutatavad sümbolid (või tühik, kui seadmata) * @return tagastab uue stringi */ String.prototype.trim = function(chars){ return this.replace(new RegExp("^["+(chars || "\\s")+"]+|["+(chars || "\\s")+"]+$", "g"),''); } /** * Muudab tekstis kõikide sõnade esimesed tähed suurtähtedeks * @return tagastab uue stringi suurte algustähtedega */ String.prototype.wordsToUpper = function(){ return this.replace(/\b\w+\b/g, function(word){ return word.substring(0,1).toUpperCase()+word.substring(1); }); }
Näide eespool defineeritud meetodite kasutamiseks:
var tekst = " siin on mingi tekst "; alert(tekst.ltrim()); // "siin on mingi tekst " alert(tekst.rtrim()); // " siin on mingi tekst" alert(tekst.trim()); // "siin on mingi tekst" // Eemaldame vasakust servast tühikud, "s" ning "i" tähed alert(tekst.ltrim("s i")); // "n on mingi tekst " // Muudame sõnade algustähed suurtähtedeks alert(tekst.wordsToUpper()); // " Siin On Mingi Tekst "
Tasub siiski meeles pidada, et JavaScripti globaalsete objektide prototype objekte ei ole soovitav ise muuta, kuna sellega võib kergelt minna konflikti teiste kasutatavate teekidega.