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