regexr
Easily compose regular expressions. Doing this with plain strings would otherwise be
tedious and error prone due to having to double-escape backslashes.
Basic example:
import r from 'regexr'
const int = /\d+/
const USD = r`\$${int}(\.${int})?`
(Note that int
is an instance of RegExp
and can be composed into the
template string, and the resulting USD
is also a RegExp
)
Regexr provides an ES6 template tag function that makes it easy to compose
RegExp
s using template strings without double-escaped hell.
In ES5 and below, we may try to compose the regular expressions like so:
const int = '\d+'
let USD = new RegExp('\$'+int+'(\.'+int+')?`) // this won't work!
but if you're experienced enough, you'd know that if you want to compose
regular expressions using ES5 strings you have to escape the escape:
const int = '\\d+'
const USD = new RegExp('\\$'+int+'(\\.'+int+')?`) // correct!
Imagine making more complex regexes! For example, compare the following two
examples achieving the same thing in ES5 and ES6 respectively:
const spaceRegex = '\\s*'
const finalRegex = new RegExp('\\(' + spaceRegex + '\\/\\[\\\\\\d+\\]\\)*$', 'g')
console.log(!!'( /[\\12358])'.match(finalRegex))
import r from 'regexr'
const spaceRegex = r`\s*`
const finalRegex = r`/\(${spaceRegex}\/\[\\\d+\]\)*$/g`
console.log(!!'( /[\\12358])'.match(finalRegex))
API
r``
template tag function
import r from 'regexr'
const r = require('regexr').default
r``
is a template tag function that converts the given string into a
RegExp without requiring double escaping. Instances of RegExp
can be mixed
into the string, and will be composed into the final RegExp
.
Example:
const digit = /\d/
const integer = r`/${digit}+/`
const number = r`/${integer}|${digit}*\.${integer}|${integer}\.${digit}*/`
Helpers
escape
(alias e
)
Escape (add backslashes to) a string for so that we can match all symbols in the
string literally when the string is used as a regex.
In the following example, we want to find occurrences of the string "value: $5.00"
in some input, so we need to escape the money
string so that the
dollar symbol ($
) doesn't represent end-of-line and the period (.
) doesn't
mean any character:
import {e} from 'regexr'
const money = '$5.00'
const fiveDollarRegex = r`value: ${e(money)}`
console.log(fiveDollarRegex)
console.log('value: $5.00'.match(fiveDollarRegex))
console.log('value: $5.50'.match(fiveDollarRegex))
Hand-picked Regexes
Regexr comes with some pre-selected regular expressions. For example, we can
rewrite the first example:
import r from 'regexr'
import * as regs from 'regexr/regexes'
const USD = r`\$${regs.integer}(\.${regs.integer})?`
where regs.integer
is an instance of RegExp
.
NOTE! Some of the following RegExps require to be wrapped in ()
when they
are being composed into bigger RegExps. These will be noted below.
regs.identifier
Matches a valid JavaScript identifier. See
this
for details.
Requires wrapping in ()
when being composed.
For example, to match a the beginning of a JS variable declaration, you could
write:
import * as regs from 'regexr/regexes'
const variableDeclaration = r`(const|let|var)\s+(${regs.identifier})\s*=`
!!'const foo ='.match(variableDeclaration)
!!'const foo bar ='.match(variableDeclaration)
regs.digit
Matches a single numerical digit (0-9).
Example:
import * as regs from 'regexr/regexes'
!!' 8 '.match(r` ${regs.digit} `)
!!' 25 '.match(r` ${regs.digit} `)
regs.integer
Matches 1 or more digits.
Example:
import * as regs from 'regexr/regexes'
!!' 432 '.match(r` ${regs.integer} `)
regs.number
Matches a JavaScript Number.
Example:
import * as regs from 'regexr/regexes'
!!'3'.match(regs.number)
!!'432'.match(regs.number)
!!'4.2'.match(regs.number)
!!'5.'.match(regs.number)
!!'.34'.match(regs.number)
regs.identifierList
Matches a comma separated list of legal JavaScript identifiers.
Example:
import * as regs from 'regexr/regexes'
const identifiersInsideParens = r`\(${regs.identifierList}\)`
!!'(foo, bar,baz)'.match(identifiersInsideParens)
!!'(foo, ,bar, baz)'.match(identifiersInsideParens)
Matches a JavaScript function header.
Example:
import * as regs from 'regexr/regexes'
const identifiersInsideParens = r`\(${regs.identifierList}\)`
!!'function() {'.match(regs.functionHeader)
!!'function asdf() {'.match(regs.functionHeader)
!!'function (asdf ) {'.match(regs.functionHeader)
!!'function asdf (asdf ) {'.match(regs.functionHeader)
!!'function asdf(asdf , asdf, ) {'.match(regs.functionHeader)
!!'function (asdf, asdf, asdfa asdf ) {'.match(regs.functionHeader)
!!'function asdf (asdf, asdf, asdfa asdf ) {'.match(regs.functionHeader)
!!'function asdf asdf (asdf, asdf, asdfa ) {'.match(regs.functionHeader)
!!'function asdf asdf (, asdf, asdf,) {'.match(regs.functionHeader)
!!'function (asdf asdf) {'.match(regs.functionHeader)
!!'function (asdf,,) {'.match(regs.functionHeader)