Skip to content

Instantly share code, notes, and snippets.

@keleshev
Last active June 19, 2022 05:36
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save keleshev/c49465caed1f114b2bb3f2b730e221ca to your computer and use it in GitHub Desktop.
Save keleshev/c49465caed1f114b2bb3f2b730e221ca to your computer and use it in GitHub Desktop.
function verboseRegExp(input) {
if (input.raw.length !== 1) {
throw Error('verboseRegExp: interpolation is not supported');
}
let source = input.raw[0];
let regexp = /(?<!\\)\s|[/][/].*|[/][*][\s\S]*[*][/]/g;
let result = source.replace(regexp, '');
return new RegExp(result);
}
let example1 = new RegExp(verboseRegExp`
(?<!\\) \s // Ignore whitespace, but not
// when escaped with backslash.
| [/][/] .* // Single-line comment.
| [/][*] [\s\S]* [*][/] // Multi-line comment.
// Note: /[\s\S]/ is same as /./s
// with dot-all flag (s).
`, 'g');
console.log(example1);
let example2 = verboseRegExp`
(0 | [1-9] [0-9]*) // Integer part with no leading zeroes
\. // Dot
[0-9]* // Fractional part (optional)
([eE] [+-]? [0-9]+)? // Exponent part (optional)
`;
console.log(example2);
function assertRegExpEqual(regexp1, regexp2) {
if (regexp1.toString() !== regexp2.toString()) {
console.error(`Assertion error: ${regexp1} !== ${regexp2}`);
} else {
console.log('.');
}
}
assertRegExpEqual(verboseRegExp`hai`, /hai/);
assertRegExpEqual(verboseRegExp`[]`, /[]/);
// Comments and whitespace are ignored;
assertRegExpEqual(verboseRegExp`x y`, /xy/);
assertRegExpEqual(/xy/, verboseRegExp`
x // ignored
y
`);
assertRegExpEqual(verboseRegExp`x /* ignored */ y`, /xy/);
// Also inside character classes:
assertRegExpEqual(verboseRegExp`[x y]`, /[xy]/);
assertRegExpEqual(verboseRegExp`[x//comment
y]`, /[xy]/); // XXX
assertRegExpEqual(verboseRegExp`[x/*z][x*/z]`, /[xz]/);
assertRegExpEqual(verboseRegExp`[x/*z*/y]`, /[xy]/);
// Escaped whitespace is not ignored:
assertRegExpEqual(verboseRegExp`\ `, /\ /);
assertRegExpEqual(verboseRegExp`\ x `, /\ x/);
assertRegExpEqual(verboseRegExp`\ `, /\ /);
// Also not in brackets:
assertRegExpEqual(verboseRegExp`[\ ]`, /[\ ]/);
// Other escapes are passed through
assertRegExpEqual(verboseRegExp`\s`, /\s/);
assertRegExpEqual(verboseRegExp`\n`, /\n/);
// Nested brackets are allowed
assertRegExpEqual(verboseRegExp` [x [y ]] `, /[x[y]]/);
@taleinat
Copy link

taleinat commented Sep 30, 2020

@keleshev, this is great!

Would you consider creating a repo for this and releasing on npmjs.com?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment