-1

In my application I have to store the function as string in datastore and load it in the runtime. RegExp matching inside the "Function" is working differently than the usual one, producing unexpected result. What is the issue here ?

var message = "I expected two hundred and three fifty ($200) and ($350) dollars from this statement";

var extractResult = (a) => {
    const inputFn = new Function("val", `
        const pattern = new RegExp(/\(([^)]+)\)/, "gi");
        const result = val.match(pattern);
        return result;
    `);

    return inputFn(a);
}

console.log("direct", message.match(new RegExp(/\(([^)]+)\)/, "gi")))
console.log("function",extractResult(message))

I need to get the output as same as in "direct" one. Or I just need to extract all strings inside the brackets, so for the above example, I'm expecting ["$200", "$350"]

Kamalakannan J
  • 2,818
  • 3
  • 23
  • 51
  • 1
    You don't need the RegExp constructor if you're using `/xyz/` regular expression literals. And you don't need the Function constructor to make a function. – Pointy Aug 30 '21 at 13:09
  • 1
    Try `console.log(\`new RegExp(/\(([^)]+)\)/, "gi");\`);` and it should be pretty clear. – VLAZ Aug 30 '21 at 13:09
  • 2
    Also note that a backslash within a template literal is an escape character, just like it is in string literals. If you want the actual backslash (so it escapes the `(` in the regular expression), you need to escape it in a template literal (or use it as a tagged template and handle it in the tag function). – T.J. Crowder Aug 30 '21 at 13:11
  • 1
    Probably a duplicate of [*Backslash Discrepancy between Regex Constructor and Literals*](https://stackoverflow.com/questions/32772399/backslash-discrepancy-between-regex-constructor-and-literals) or [*Backslashes - Regular Expression*](https://stackoverflow.com/questions/10769964/backslashes-regular-expression-javascript). – RobG Aug 30 '21 at 13:18
  • 1
    On a separate note, I find it concerning that you're storing a *function* as a string. And that's a hand-written string, not even a serialised function. I'd strongly suggest you only store the configuration needed, rather than the whole of the function. – VLAZ Aug 30 '21 at 13:18
  • 1
    @RobG sort of but not exactly. It's not the RegExp constructor that receives a string - the entire RegExp constructor call *is* a string. – VLAZ Aug 30 '21 at 13:20
  • @VLAZ—yes, but they put it in context. :-) – RobG Aug 30 '21 at 14:19

1 Answers1

0

You can define your regular expression as literal expression. Since your function is inside a string (literal), you will need to escape your escape characters (\).

const message = "I expected two hundred and three fifty ($200) and ($350) dollars from this statement";

const extractResult = (message) => {
  const inputFn = new Function('val', `
    const pattern = /\\([^)]+\\)/gi;
    const result = val.match(pattern);
    return result;
  `);

  return inputFn(message);
}

console.log('direct', message.match(/\([^)]+\)/gi));
console.log('function', extractResult(message))
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
  • 1
    This does not really provide an answer to the question. *"Your function is a string literal"*: no, there is a string literal that is passed to the `Function` constructor, which creates a function object. This answer merely converts the `new Function` variant to be rather equal to the other variant, but doesn't explain why there was a problem. – trincot Aug 30 '21 at 13:15
  • @Mr.Polywhirl this is working, but why it's still having brackets, could you update the solution to extract the values without the brackets in the result(please do it via regex grouping not with `result.filter()`), so that I can accept it. – Kamalakannan J Aug 31 '21 at 04:45