Analizzate un'espressione
Un’espressione aritmetica consiste in 2 numeri e un operatore tra di essi, ad esempio:
1 + 21.2 * 3.4-3 / -6-2 - 2
L’operatore è uno fra: "+", "-", "*" o "/".
Potrebbero esserci ulteriori spazi all’inizio, alla fine o tra gli elementi.
Create una funzione parse(expr) che riceva un’espressione e restituisca un array di 3 elementi:
- Il primo numero.
- L’operatore.
- Il secondo numero.
Ad esempio:
let [a, op, b] = parse("1.2 * 3.4");
alert(a); // 1.2
alert(op); // *
alert(b); // 3.4
L’espressione regolare per un numero è: -?\d+(\.\d+)?. L’abbiamo creata nell’esercizione precedente.
Per trovare un operatore usiamo [-+*/]. Il trattino - va posto all’inizio nelle parentesi quadre, in mezzo significherebbe un intervallo di caratteri, mentre noi vogliamo soltanto il carattere -.
Dovremmo fare l’escape dello slash / dentro una regexp JavaScript /.../, lo faremo dopo.
Abbiamo bisogno di un numero, un operatore, e quindi un altro numero. Tra di essi ci possono essere spazi opzionali.
Ecco l’intera espressione regolare: -?\d+(\.\d+)?\s*[-+*/]\s*-?\d+(\.\d+)?.
Questa consta di 3 parti, intervallate da \s*:
-?\d+(\.\d+)?– il primo numero,[-+*/]– l’operatore,-?\d+(\.\d+)?– il secondo numero.
Per rendere ciascuna di queste parti un elemento separato dell’array di risultati le racchiudiamo tra parentesi: (-?\d+(\.\d+)?)\s*([-+*/])\s*(-?\d+(\.\d+)?).
In azione:
let regexp = /(-?\d+(\.\d+)?)\s*([-+*\/])\s*(-?\d+(\.\d+)?)/;
alert( "1.2 + 12".match(regexp) );
Il risultato include:
result[0] == "1.2 + 12"(l’intera corrispondenza)result[1] == "1.2"(il primo gruppo(-?\d+(\.\d+)?), il primo numero compresa la parte decimale)result[2] == ".2"(il secondo gruppo(\.\d+)?, la prima parte decimale)result[3] == "+"(il terzo gruppo([-+*\/]), l’operatore)result[4] == "12"(il quarto gruppo(-?\d+(\.\d+)?), il secondo numero)result[5] == undefined(il quinto gruppo(\.\d+)?, l’ultima parte decimale è assente, quindi equivale ad undefined)
Il nostro scopo è ottenere i numeri e l’operatore, senza l’intera corrispondenza o le parti decimali, quindi “puliamo” un po’ il risultato.
L’intera corrispondenza (il primo elemento dell’array) possiamo rimuoverla con result.shift().
I gruppi che contengono le parti decimali (gli elementi 2 e 4) (.\d+) li escludiamo aggiungendo ?: all’inizio: (?:\.\d+)?.
La soluzione finale:
function parse(expr) {
let regexp = /(-?\d+(?:\.\d+)?)\s*([-+*\/])\s*(-?\d+(?:\.\d+)?)/;
let result = expr.match(regexp);
if (!result) return [];
result.shift();
return result;
}
alert( parse("-1.23 * 3.45") ); // -1.23, *, 3.45