Regexes in JavaScript are a fantastic tool for matching text, manipulating strings, performing validations, and a myriad of other tasks (just don’t try to use them to parse HTML!) Thanks to ever-improving Unicode support with the u
flag and Unicode property escapes, regexes in Javascript have never been more powerful.
However, one area where JavaScript regexes have consistently fallen behind is developer experience. In Ruby, interpolation of variables into regexes is supported by default, and support for multiline whitespace indentation and comments can easily be enabled with the x
flag. In JavaScript, meanwhile, you end up clumsily joining strings together using the RegExp
constructor, using lots of double-escaped backslashes. Without comments or proper indentation, it’s no wonder that people say regexes are a write-only language.
That’s why I built fancy-regex
! This tiny npm package uses the power of tagged template literals to provide a developer experience very similar to Ruby’s /#{regex}/x
.
Let’s take a quick look at a couple of examples:
const myFancyRegex = regex`.{${4 + 1}}`
Simple enough. If you don’t need to use any flags, the regex
function is directly callable on template strings.
If you do need flags, you can pass them to regex
first:
const myCaseInsensitiveRegex = regex('i')`
^
abc
${myFancyRegex} # seamlessly interpolate other regexes
\w\d\b\0\\ # look Mom, no double escaping!
...
\r\n\t\x20 # use "\x20" to match a literal space
$
`
The compiled regex here is /^abc.{5}\w\d\b\0\\...\r\n\t\x20$/i
— hopefully you’ll agree that the commented and indented version is a lot more readable!
If you like, you can pass the the flags in an options object instead:
const myRegexWithOptions = regex({
unicode: true,
global: true,
})`
^
💩+ # with unicode enabled, this matches by codepoint
$
`
Here, the compiled regex is /^💩+$/gu
.
Because fancy-regex uses the raw template string under the hood, the only things you’ll need to escape that you wouldn’t in a regex literal are backticks (`
) and the sequence ${
. Whitespace and hash symbols (#
) must also be escaped if you don’t want them to be removed.
On the flipside, you no longer need to escape forward-slashes, which makes URL matching even easier than before!
regex`https://dev\.to/top/(week|month)`
// compiles to /https:\/\/dev\.to\/top\/(week|month)/
This is the first npm package I’ve ever published, so I’d love to hear your feedback on v0.X.X! 🧡🧡🧡