edutecnica

Stringhe in JavaScript

         

Le stringhe di testo possono essere usate in linguaggio JavaScript dichiarandole come variabili già inizializzate

var str='alfa beto';

oppure (indifferentemente) istanzandole con l'operatore new attraverso il loro costruttore : String

var str = new String('alfa beto');

In tutti e due i casi avremo creato un oggetto di tipo stringa che può essere visto come un array (come in linguaggio C) cioè una struttura di caratteri che può essere gestita grazie ad un indice con valore progressivamente crescente che assume valore 0 per il primo carattere della sequenza.

E' possibile testare le proprietà delle stringhe utilizzando la console JavaScript che può essere attivata attivando la combinazione di tasti CTRL-SHIFT-J su Chrome e Firefox, mentre su Safari bisogna premere CMD-ALT-J utilizzando files salvati con estensione .html scrivendo con un normale editor di testo (blocco note) uno scritto JS incorporato in una pagina web come mostrato qui di seguito:
<!Doctype html><html>
<body>
<script>
var str='alfabeto';
console.log(str);//__>alfabeto
</script>
</body>
</html>

Se una stringa è un oggetto, avremo a disposizione una serie di metodi di indubbia utilità, il primo dei quali è il metodo length.
stringa.length
restituisce la lunghezza della stringa

var str='alfa beto';
console.log(str.length);//_______>9

Il metodo charAt() è del tutto equivalente a quello usato in linguaggio Java su oggetti di tipo String.
stringa.charAt(index)
dove index è un numero compreso tra 0 e lunghezza della stringa-1; viene restituito il carattere all'indice specificato

var str='alfa beto';
console.log(str.charAt(5));//___>b

Il metodo charCodeAt() può essere implementato da un comando del tipo
stringa.charCodeAt(index);
dove index è un numero compreso tra 0 e lunghezza della stringa-1; restituisce il codice ASCII del carattere all'indice specificato.

var str='alfa beto';
console.log(str.charCodeAt(5));//___>98

Il metodo concat() serve per concatenare delle stringhe
stringa1.concat(stringa2, stringa3 [, ..., stringaN]);
anche se già sappiamo che questo è reso possibile anche dall'operatore +.

var str1='alfa';
var str2='beto';
console.log(str1.concat(str2));//_>alfabeto
console.log(str1+str2);//_________>alfabeto

Il metodo indexOf() è privilegiato per vedere se in una stringa vi è una specifica sottostringa o carattere.
stringa1.indexOf(stringa2[, daIndex]) ;
esso,intercetta la presenza della sottostringa stringa2 nella stringa stringa1. E' possibile (opzionalmente) far partire la ricerca da un indice (daIndex) specificato.

var str='alfa beto';
console.log(str.indexOf('bet'));//__>5

Questo metodo, restituisce -1 se l'occorrenza cercata non è stata trovata.
Bisogna specificare che nel caso l'occorrenza cercata appaia molteplici volte nella stringa di ricerca, verrà restituita la posizione della prima occorrenza trovata.

Il metodo lastIndexOf() esprimibile nella forma
stringa1.lastIndexOf(stringa2[, daIndex]) ;
intercetta la presenza della sottostringa stringa2 nella stringa stringa1 e ne restituisce la posizione dell'ultima occorrenza (eventualmente) trovata.
Anche in questo caso possibile far partire la ricerca da un indice specificato.

var str='alfa beto beta';
console.log(str.lastIndexOf('be'));//___>10

anche in questo caso viene restituito -1 se la stringa cercata non viene trovata.

Un metodo alternativo a indexOf() è il metodo search() espresso dalla sintassi
stringa1.search(stringa2);
restituisce la prima posizione della stringa2 nella stringa1 oppure restituisce -1 se stringa2 non viene trovata.

var str='alfa beto';
console.log(str.search('bet'));//__>5

Non si può dire che il metodo indexOf() ed il metodo search() siano equivalenti perchè il primo prevede la presenza di un indice opzionale da cui far partire la ricerca ed il secondo no.
Per contro, search() è in grado di supportare espressioni regolari in modo più efficiente di indexOf().

Il metodo slice() può essere usato per estrarre sottostringhe da una stringa
string.slice(inizio [, fine] );
come si vede l'indice che specifica la fine è opzionale e se non è presente verrà estratta la sottostringa che va dalla posizione 'inizio' fino alla fine della stringa di origine.

var str='alfa beto';
console.log(str.slice(5,8));//____>bet
console.log(str.slice(5));//______>beto
console.log(str.slice(-7,-2));//__>fa be

come si vede è possibile usare anche degli indici negativi secondo la convenzione qui riportata

Il metodo substring() è simile a slice()
string.substring(inizio [,fine]);
ma non può usare indici negativi

var str='alfa beto';
console.log(str.substring(5,8));//___>bet

Anche il metodo substr() è simile a slice() e come esso può supportare indici negativi
stringa.substr(inizio[,lunghezza]);
la differenza sta che il secondo parametro opzionale, specifica la lunghezza della stringa da estrarre

var str='alfa beto';
console.log(str.substr(5,3));//___>bet
console.log(str.substr(-4,3));//___>bet

Il metodo replace() permette di effettuare la sostituzione dell'occorrenza ricercata.
stringa.replace(stringa1,stringa2);
usato in concomitanza di espressioni regolari, questo comando, può essere ulteriormente potenziato.

var str='alfa beta';
console.log(str.replace('beta','tau'));//___>alfa tau

Il metodo split() è in grado di spezzare una stringa basandosi su un separatore prefissato e di ridurla ad un array di sottostringhe o caratteri
stringa.split([comma][, limite]);
dove comma è appunto il carattere separatore e limite il valore massimo di 'spezzettamenti' possibili

var str='alfa,beta,gamma,delta';
var vet=str.split(',');
console.log(vet[2]);//___>gamma

toUpperCase( ) ha il compito di commutare in maiuscolo la stringa sottoposta questo metodo
stringa.toUpperCase()
ad esempio

var str='Alfa Beta';
console.log(str.toUpperCase());//___>ALFA BETA

Per analogia deve esistere anche il metodo opposto toLowerCase() con sintassi
stringa.toLowerCase()
entrambi i metodi restituiscono una stringa

var str='Alfa Beta';
console.log(str.toLowerCase());//___>alfa beta


Espressioni regolari

         

Le espressioni regolari sono un sistema per eseguire il controllo sintattico di una stringa.
Costituiscono un lessico particolare comune a molteplici linguaggi di programmazione.

Una espressione regolare è un tipo di oggetto istanziato tramite l'operatore new e realizzato dal costruttore RegExp oppure può essere rappresentato come un valore letterale racchiuso tra barre (/.../).

var re=new RegExp('alfabeto');

oppure

var re=/alfabeto/;

Nel primo caso, col costruttore RegExp la stringa viene interpretata e come tale, al suo interno, valgono le solite regole per le barre rovesciate ad esempio \n per il ritorno a capo, \t per la tabulazione etc..
Nel secondo caso con la sequenza di caratteri racchiusa tra barre semplici, le barre rovesciate (retroverse) sono considerate diversamente, perche in quest'ultimo caso abbiamo a che fare con una espressione regolare .

Alcuni caratteri come '?', '*' e '+' hanno significati speciali nelle espressioni regolari e vanno preceduti da una barra rovesciata

var s=/tri\+/;


Metodo test

         

Le espressioni regolari dispongono di diversi metodi; tra questi il più importante è il metodo test()

console.log(/mos/.test('termostato'));//_>true
console.log(/mas/.test('termostato'));//_>false

che restituisce true solo se l'espressione è contenuta nella stringa di test.
Si potrebbe obiettare che per cercare la stringa 'mos' si può usare anche il metodo indexOf, ma le espressioni regolari permettono di specificare in modi diversi la presenza di una sottostringa in una stringa o in un testo.

Se si vuole verificare che una stringa che parta con la sottostringa 'ciao' useremo l'operatore '^' accento circonflesso


console.log(/^ciao/.test('ciao beh'));//_________>true
true console.log(/^ciao/.test('beh ciao'));//___>false

se si vuole verificare che una stringa termini con la sottostringa 'ciao' si usa il simbolo $.
console.log(/ciao$/.test('ciao'));//_________>true
console.log(/ciao$/.test('beh ciao'));//_____>true
console.log(/ciao$/.test('ciao a te'));//____>false

Ad esempio se vogliamo intercettare la presenza di un numero qualsiasi all'interno di una stringa si possono usare indifferentemente queste due espressioni

console.log(/[0123456789]/.test('forse 6 distratto'));//_>true
console.log(/[0-9]/.test('forse 6 distratto'));//________>true

Si capisce come le espressioni regolari siano caratterizzate da una loro propria sintassi dove si possono definire interi intervalli:

[a-z] tutti i caratteri minuscoli
[0-9] tutte le cifre
[a-zA-Z] tutti i caratteri minuscoli o maiuscoli

queste sequenze possono essere sostituite da specifici simboli convenzionali:

\d qualunque cifra
\w un carattere alfanumerico
\s qualunque spazio vuoto (spazio, tabulazione, ritorno a capo)
\D un carattere che non sia un numero
\W un carattere non alfanumerico
\S un carattere che non sia uno spazio vuoto
.   qualunque carattere escluso il ritorno a capo

è ammesso, dunque utilizzare particolari 'pattern' per intercettare la presenza di dati specifici; ad esempio, volendo rilevare la presenza di una data nel formato 20-11-2018 16:00 si può usare l'espressione

var dt=/\d\d-\d\d-\d\d\d\d \d:\d/;
console.log(dt.test('20-11-2018 16:00');//______>true

Le barre rovesciate possono essere inserite anche all'interno delle parentesi quadre, ad es. [\d.] indica qualunque cifra o punto.
Per invertire la condizione logica di ricerca, cioè per dire che si vogliono trovare tutti i caratteri eccetto quelli indicati si può inserire un accento circonflesso

var bin=/[^01]/;
console.log(bin.test('0011010101'));//____>false
console.log(bin.test(('acppb'));//________>true


Sequenze ripetute

         

Per intercettare una sequenza di caratteri è possibile inserire il segno + dopo un carattere; ; ad ese. /\d+/ può intercettare uno o più caratteri cifra

console.log(/"\d+"/.test('"123"'));//___>true
console.log(/"\d+"/.test('""'));//______>false
console.log(/"\d*"/.test('"123"'));//___>true
true console.log(/"\d*"/.test('""'));//_>true

L'asterisco * ha significato simile al + con la differenza che la sequenza si può trovare zero o più volte.
Il punto di domanda come l'asterisco è un quantificatore che rende parte della sequenza facoltativa, nel senso che la si può trovare zero o una volta.
Combinando il punto e l'asterisco .* si può indicare una qualsiasi sequenza di caratteri che può essere presente 0 o più volte .

console.log(/.*word.*/.test('xwordwin'));//__>true
console.log(/.*word.*/.test('winword'));//___>true
console.log(/.*word.*/.test('excel'));//_____>false

Per indicare che una sequenza deve essere presente il numero di volte dato bisogna usare le parentesi graffe .
Se ad esempio viene specificato {4} dopo un elemento indica che la sequenza deve presentarsi esattamente 4 volte; in questo modo è possibile specificare anche un intervallo : {2,4} indica che l'elemento si deve presentare almeno due e al massimo 4 volte

var dt=/\d{1,2}-\d{1,2}-\d{4} \d{1,2}:\d{1,2}/;
console.log(dt.test('20-1-2018 16:00'));//______>true


Raggruppamento di sottoespressioni

         

Per poter usare l'operatore + su più di un elemento per volta si possono usare le parentesi tonde.
Una parte di espressione regolare racchiusa tra parentesi tonde conta come elemento singolo per gli operatori che la seguono

var exp=/We+(he+)+/i;
console.log(exp.test('weeheeheee'));//______>true

il primo ed il secondo segno + si applicano solo alla lettera 'e' di di We e di he; il terzo segno + si applica a tutto il gruppo (he+) trovandone una o più sequenze.
La lettera i alla fine dell'espressione indica che non si fanno differenze tra lettere maiuscole e minuscole; per cui viene ritenuta valida anche la lettera w minuscola all'inizio della sequenza.


Metodo exec

         

Come si è potuto constatare il metodo test() è il sistema più semplice per trovare una corrispondenza in un'espressione regolare: esso indica solo se la corrispondenza è stata trovata. Le espressioni regolari hanno anche un metodo exec() che restituisce null se non si trovano corrispondenze, altrimenti restituisce un oggetto con informazioni sulle corrispondenze trovate.

var exp=/\d+/.exec('uno due 3');
console.log(exp);//________>[3]
console.log(exp.index);//__>8

Nel primo caso viene riportata la prima occorrenza trovata e nel secondo, attraverso la proprietà index, l'indice della posizione nella stringa dell'occorrenza cercata .
Il metodo match() per gli oggetti stringa si comporta in modo simile.

console.log('Cap.3 cap.31'.match(/\d+/));//______>["3"]
console.log('Cap.3 cap.31'.match(/\d+/g));//______>["3","31"]

Si vede come match() intercetta tutte le occorrenze dove appare un carattere numerico, se viene usata l'opzione g (global) sistemandole in un array di stringhe.
Se non viene specificato g l'array sarà costituito solo dalla prima occorrenza trovata.


Metodo replace

         

Come visto, gli oggetti stringa hanno un metodo replace, che può essere usato per sostituire una sottostringa in una stringa .

console.log('ulla'.replace('u','e'));//____>ella

Il primo argomento può anche essere un espressione regolare. In questo caso, viene sostituito il primo elemento dove l'espressione regolare trova corrispondenza.
Aggiungendo un opzione g (globale) all'espressione regolare, vengono sostituiti tutti gli elementi corrispondenti e non solo il primo.

console.log('Protoattinio'.replace(/[oa]/,'u'));
//______>Prutoattinio (solo la prima occorrenza)
console.log('Protoattinio'.replace(/[oa]/g,'u'));
//______>Prutuuttiniu (tutte le occorrenze)

Il metodo replace viene ulteriormente potenziato se usato in concomitanza di espressioni regolari .
Per esempio, immaginiamo di avere una lunga stringa che contiene nomi di persone, un nome per riga, con prima il cognome poi il nome.
Se vogliamo scambiare la posizione dei nomi ed eliminare la virgola per arrivare al formato nome-cognome possiamo usare il seguente codice:


I codici $1 e $2 nella stringa di sostituzione si riferiscono ai gruppi tra parentesi della sequenza.
$1 viene sostituito dal testo trovato nel primo gruppo, $2 da quello del secondo e così via fino a $9.
Alla corrispondenza nel suo insieme si fa riferimento con $&.


Metodo search

         

Sulle stringhe non si può richiamare il metodo indexOf con un'espressione regolare.
Esiste, però, un altro metodo, search, che accetta come argomento un'espressione regolare.
Come indexOf, restituisce l'indice della prima posizione dove si trova corrispondenza oppure -1 se non ne trova.

console.log(' alfa'.search(/\S/));//__>2
console.log(' '.search(/\S/));//______>-1

Purtroppo, non c'è modo di indicare che la corrispondenza deve partire da una posizione data, come si può fare invece con il secondo argomento di indexOf.


Riepilogo

         

Le espressioni regolari sono oggetti che rappresentano sequenze di caratteri in una stringa.
Dispongono di una loro sintassi per esprimere queste sequenze.

/abc/                Una sequenza di caratteri
/[abc]/         Qualunque carattere in una serie di carattere
/[^abc]/      Qualunque carattere non in una serie di caratteri
/[0-9]/         Qualunque carattere compreso in un intervallo
/x+/                    Una o più occorrenze del carattere x
/x+?/                 Una o più occorrenze, non globali
/x*/                    Zero o più ricorrenze
/x?/                     Zero o una ricorrenza
/x{2,4}/       Tra due e quattro occorrenze
/(abc)/           Un gruppo
/a|b|c/           Una di una serie di sequenze
/\d/                    Qualunque carattere cifra
/\w/                    Un carattere alfanumerico (carattere word)
/\s/                    Qualunque carattere spazio vuoto
/./                       Qualunque carattere tranne il ritorno a capo
/\b/                    Un confine di parola
/^/                        Inizio dell' input
/$/                        Fine dell' input