DmitrySoshnikov / babel-plugin-transform-modern-regexp

Babel plugin for modern RegExp features in JavaScript
MIT License
81 stars 8 forks source link

Implement single-escape of meta chars mode in Template literal regexes #4

Closed DmitrySoshnikov closed 7 years ago

DmitrySoshnikov commented 7 years ago

By default we use natural "double-escaping" of meta-char per JS.

E.g.:

new RegExp(`\\d+`);

Instead of:

new RegExp(`\d+`);

This is a standard JS way, however the second approach looks much cleaner, and correlates with the syntax in regexp literals: /\d+/.

We can easily implement the second approach: for this we should use raw value of a template string, instead of cooked value, which we use now.

To see the difference between raw, and cooked values, check this example in AST explorer.

I.e. for the template string:

`\n\d`

We get the following values:

{
  "raw": "\\n\\d",
  "cooked": "\nd"
}

So the raw value directly corresponds to the auto doubly-escaped values which we need.

However, there is an issue with \1, ... \7 values: they are disallowed in template strings (as Octal numbers). And these values can normally be used in regexes as backreferences to captured groups.

Therefore, we can enable the single-escape mode (using raw value), but still require to escape reference with \\1, etc. This brings slight inconsistency, however, not often one needs to backreference in regexes, and the convenience of using \d+ instead of \\d+ overweights it. Technically, we'll need to replace \\\\1 to \\1 in the raw value for such numbers.

Since this is "unnatural" way for JS strings (but still much more convenient than default way), we can enabled this behind a transform option singleEspaceMeta.

DmitrySoshnikov commented 7 years ago

Fixed in https://github.com/DmitrySoshnikov/babel-plugin-transform-modern-regexp/commit/4f050440f373c6423902acbdd93b41fc1b921fae via re shorthand (useRe option).