silentmatt / expr-eval

Mathematical expression evaluator in JavaScript
http://silentmatt.com/javascript-expression-evaluator/
MIT License
1.2k stars 237 forks source link

Illegal escape sequences #161

Closed janeivind closed 6 years ago

janeivind commented 6 years ago

I added my custom function to data for regexp, as I found a bit of a showstopper in https://github.com/silentmatt/expr-eval/blob/31d9b13b455d8b43f811bf9fb0869199fcca2399/src/token-stream.js#L181

I haven't read all your code, but is there any possibility in allowing more sequences?

  function execRegExp(value, pattern) {
    var result = false;
    try {
      console.log(pattern); 
      // pattern ^[a-zA-Z]{2}(\s)?\d{5}$ is reduced to ^[a-zA-Z]{2}(s)?d{5}$
      // pattern ^[a-zA-Z]{2}(\\s)?\\d{5}$ gives an error
      console.log(value)
      result = new RegExp(pattern).exec(value) !== null;
    } catch (e) {
      // Ignore
    }
    return result;
  }
silentmatt commented 6 years ago

The second version (with \\) should work, but you might need an additional level of escaping if you're including the pattern as string literal in JavaScript. Once for the expression evaluator, and again for the JavaScript parser.

So it would be something like this:

var parser = new Parser();
parser.evaluate('execRegExp("ab 12345", "^[a-zA-Z]{2}(\\\\s)?\\\\d{5}$")');
// The parser gets this string literal: "^[a-zA-Z]{2}(\\s)?\\d{5}$"
// ... which turns into the value       "^[a-zA-Z]{2}(\s)?\d{5}$"

Alternatively, if you're in an environment that supports template literals, you could use String.raw to clean it up a little:

var parser = new Parser();
parser.evaluate(String.raw`execRegExp("ab 12345", "^[a-zA-Z]{2}(\\s)?\\d{5}$")`);