[ Web Proxy ]
URL:
Viewing: https://da.javascript.info/task/parse-expression [Back]  [Original]

Parse an expression
DA

Vi nsker at gre dette open source-projekt tilgngeligt for folk over hele verden.

Hjlp med at overstte indholdet af denne tutorial til dit sprog!

    Sg p Javascript.info:
    Sg i tutorialen:
    Lyst temaMrkt tema
    DanskEnglishEspaolFranaisIndonesiaItalianoTrkeOzbek
    tilbage til lektionen
    Dette materiale er kun tilgngeligt p flgende sprog: , English, Espaol, Franais, Indonesia, Italiano, , , , Trke, , Ozbek, . Hjlp os med at overstte til Dansk.

    Parse an expression

    An arithmetical expression consists of 2 numbers and an operator between them, for instance:

    • 1 + 2
    • 1.2 * 3.4
    • -3 / -6
    • -2 - 2

    The operator is one of: "+", "-", "*" or "/".

    There may be extra spaces at the beginning, at the end or between the parts.

    Create a function parse(expr) that takes an expression and returns an array of 3 items:

    1. The first number.
    2. The operator.
    3. The second number.

    For example:

    let [a, op, b] = parse("1.2 * 3.4");
    
    alert(a); // 1.2
    alert(op); // *
    alert(b); // 3.4
    lsning

    A regexp for a number is: -?\d+(\.\d+)?. We created it in the previous task.

    An operator is [-+*/]. The hyphen - goes first in the square brackets, because in the middle it would mean a character range, while we just want a character -.

    The slash / should be escaped inside a JavaScript regexp /.../, well do that later.

    We need a number, an operator, and then another number. And optional spaces between them.

    The full regular expression: -?\d+(\.\d+)?\s*[-+*/]\s*-?\d+(\.\d+)?.

    It has 3 parts, with \s* between them:

    1. -?\d+(\.\d+)? the first number,
    2. [-+*/] the operator,
    3. -?\d+(\.\d+)? the second number.

    To make each of these parts a separate element of the result array, lets enclose them in parentheses: (-?\d+(\.\d+)?)\s*([-+*/])\s*(-?\d+(\.\d+)?).

    In action:

    let regexp = /(-?\d+(\.\d+)?)\s*([-+*\/])\s*(-?\d+(\.\d+)?)/;
    
    alert( "1.2 + 12".match(regexp) );

    The result includes:

    • result[0] == "1.2 + 12" (full match)
    • result[1] == "1.2" (first group (-?\d+(\.\d+)?) the first number, including the decimal part)
    • result[2] == ".2" (second group(\.\d+)? the first decimal part)
    • result[3] == "+" (third group ([-+*\/]) the operator)
    • result[4] == "12" (forth group (-?\d+(\.\d+)?) the second number)
    • result[5] == undefined (fifth group (\.\d+)? the last decimal part is absent, so its undefined)

    We only want the numbers and the operator, without the full match or the decimal parts, so lets clean the result a bit.

    The full match (the arrays first item) can be removed by shifting the array result.shift().

    Groups that contain decimal parts (number 2 and 4) (.\d+) can be excluded by adding ?: to the beginning: (?:\.\d+)?.

    The final solution:

    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

    As an alternative to using the non-capturing ?:, we could name the groups, like this:

    function parse(expr) {
      let regexp = /(?<a>-?\d+(?:\.\d+)?)\s*(?<operator>[-+*\/])\s*(?<b>-?\d+(?:\.\d+)?)/;
    
      let result = expr.match(regexp);
    
      return [result.groups.a, result.groups.operator, result.groups.b];
    }
    
    alert( parse("-1.23 * 3.45") );  // -1.23, *, 3.45;

    Web Proxy Viewer  |  New URL  |  Original Page