Awesome
regexr
Easily compose regular expressions. Doing this with plain strings would otherwise be tedious and error prone due to having to double-escape backslashes.
npm install regexr
Basic example:
import r from 'regexr'
const int = /\d+/
const USD = r`\$${int}(\.${int})?` // f.e. $3.45 or $5
(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:
// in ES5, the double escaping can get confusing:
const spaceRegex = '\\s*'
const finalRegex = new RegExp('\\(' + spaceRegex + '\\/\\[\\\\\\d+\\]\\)*$', 'g')
console.log(!!'( /[\\12358])'.match(finalRegex)) // true
// in ES6, we don't have to double escape, thanks to regexr:
import r from 'regexr'
const spaceRegex = r`\s*`
const finalRegex = r`/\(${spaceRegex}\/\[\\\d+\]\)*$/g`
console.log(!!'( /[\\12358])'.match(finalRegex)) // true
API
r``
template tag function
import r from 'regexr'
// or
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}*/` // f.e. 4.2, .5, 5.
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) // /value: \$5\.00/
console.log('value: $5.00'.match(fiveDollarRegex)) // true
console.log('value: $5.50'.match(fiveDollarRegex)) // false
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})?` // f.e. $3.45 or $5
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) // true
!!'const foo bar ='.match(variableDeclaration) // false
regs.digit
Matches a single numerical digit (0-9).
Example:
import * as regs from 'regexr/regexes'
!!' 8 '.match(r` ${regs.digit} `) // true
!!' 25 '.match(r` ${regs.digit} `) // false
regs.integer
Matches 1 or more digits.
Example:
import * as regs from 'regexr/regexes'
!!' 432 '.match(r` ${regs.integer} `) // true
regs.number
Matches a JavaScript Number.
Example:
import * as regs from 'regexr/regexes'
!!'3'.match(regs.number) // true
!!'432'.match(regs.number) // true
!!'4.2'.match(regs.number) // true
!!'5.'.match(regs.number) // true
!!'.34'.match(regs.number) // true
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) // true
!!'(foo, ,bar, baz)'.match(identifiersInsideParens) // false
regs.functionHeader
Matches a JavaScript function header.
Example:
import * as regs from 'regexr/regexes'
const identifiersInsideParens = r`\(${regs.identifierList}\)`
!!'function() {'.match(regs.functionHeader) // true
!!'function asdf() {'.match(regs.functionHeader) // true
!!'function (asdf ) {'.match(regs.functionHeader) // true
!!'function asdf (asdf ) {'.match(regs.functionHeader) // true
!!'function asdf(asdf , asdf, ) {'.match(regs.functionHeader) // true
!!'function (asdf, asdf, asdfa asdf ) {'.match(regs.functionHeader) // false
!!'function asdf (asdf, asdf, asdfa asdf ) {'.match(regs.functionHeader) // false
!!'function asdf asdf (asdf, asdf, asdfa ) {'.match(regs.functionHeader) // false
!!'function asdf asdf (, asdf, asdf,) {'.match(regs.functionHeader) // false
!!'function (asdf asdf) {'.match(regs.functionHeader) // false
!!'function (asdf,,) {'.match(regs.functionHeader) // false