Last active
April 12, 2021 22:16
-
-
Save shannonmoeller/b4f6fbab2ffec56213e7 to your computer and use it in GitHub Desktop.
Multiline Regular Expressions using ES6 Template Strings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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
brilliant...helped make a parser im working on MUCH easier to work with