Skip to content

Instantly share code, notes, and snippets.

@mingliangguo
Forked from shannonmoeller/multiline-regexp.js
Created April 11, 2019 13:38
Show Gist options
  • Save mingliangguo/fd921e78b5e70683539d0aa133dd801e to your computer and use it in GitHub Desktop.
Save mingliangguo/fd921e78b5e70683539d0aa133dd801e to your computer and use it in GitHub Desktop.
Multiline Regular Expressions using ES6 Template Strings
/**
* Inspired by XRegExp via 2ality
* http://www.2ality.com/2012/12/template-strings-xregexp.html
* http://xregexp.com/
*/
import test from 'ava';
export function rx(flags) {
const trailingComments = /\s+#.*$/gm;
const surroundingWhitespace = /^\s+|\s+$/gm;
const literalNewlines = /[\r\n]/g;
return (strings, ...values) => {
function toPattern(pattern, rawString, i) {
var value = values[i];
if (value == null) {
return pattern + rawString;
}
if (value instanceof RegExp) {
value = value.source;
}
return pattern + rawString + value;
}
const compiledPattern = strings.raw
.reduce(toPattern, '')
.replace(trailingComments, '')
.replace(surroundingWhitespace, '')
.replace(literalNewlines, '');
return new RegExp(compiledPattern, flags);
};
}
test('should compile a multiline RegExp', async assert => {
// flags on partials are ignored
const open = /\/\*\*/g;
const close = /\*\//m;
const expression = rx('gm')`
# Match a non-recursive block comment
(
# Must be first thing on a line
^[\t ]*
${open} # Trailing comment
(
# Match any character including newlines (non-greedy)
[\s\S]*?
)
${close}
)
# Grab trailing newlines and discard them
[\r\n]*
`;
assert.same(expression, /(^[\t ]*\/\*\*([\s\S]*?)\*\/)[\r\n]*/gm);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment