Skip to content

Instantly share code, notes, and snippets.

@rkatic
Last active January 19, 2021 07:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rkatic/2c54bf9e2bd3531a390f2e982399ff50 to your computer and use it in GitHub Desktop.
Save rkatic/2c54bf9e2bd3531a390f2e982399ff50 to your computer and use it in GitHub Desktop.
re - raw, multi-line, auto-escaping, composable, RegExp sexy creations
'use strict'
const objToStringMethod = Object.prototype.toString
const reRegExpChar = /[\\^$.*+?()[\]{}|]/g
const reUnescapedSpaces = /(?<!\\)\s+/g
const reHasSpace = /\s/
const compact = raw => reHasSpace.test(raw) ? raw.replace(reUnescapedSpaces, '') : raw
const escape = val => String(val).replace(reRegExpChar, '\\$&')
const toSource = val => {
switch (objToStringMethod.call(val)) {
case '[object RegExp]': return val.source
case '[object Function]': return val(escape)
case '[object Array]': return val.map(escape).join('|')
default: return escape(val)
}
}
const reWith = (_, flags) => ({raw}, ...values) => {
let source = compact(raw[0])
for (let i = 0; i < values.length;) {
source += toSource(values[i])
source += compact(raw[++i])
}
return new RegExp(source, flags)
}
exports.re = new Proxy(reWith(1, ''), { get: reWith })

re

becouse /.../ are too dense, and new RegExp(...) too messy

Examples

In examples below, _ is the lodash library.

Example 1

re.i`\b${myName}\b`.test('My name is Robert.')

is equivelant to

new RegExp(`\\b${_.escapeRegExp(myName)}\\b`, 'i').test('My name is Robert.')

Example 2

text.replace(re.gi`\b(?:${badWords})\b`, 'BIP')

is equivelant to

const reBadWords = new RegExp(`\\b(?:${badWords.map(_.escapeRegExp).join('|')})\\b`, 'gi')
text.replace(reBadWords, 'BIP')

Example 3

Named groups are great, but not too practical if limited to one line with no spaces!

re ignores (removes) whitespaces except those that you explicitly escape (\ ).

const reISODate = re`
  (?<date>
    (?<YYYY> \d{4})
    -
    (?<MM> \d{2})
    -
    (?<DD> \d{2})   ${[/* Here a comment if you need one */]}
  )
  (?: 
    (?: T | \ )
    (?<time>
      (?<HH> \d{2})
      :
      (?<mm> \d{2})
      :
      (?<ss> \d{2})
      (?:
        \.
        (?<ms> \d{3})
      )?
    )
    (?:
      (?<zone> Z) | (?<offset> [+-]\d\d(?: :\d\d )?)
    )?
  )?
`

const reJustISODate = re`^ ${reISODate} $`

console.log(new Date().toISOString().match(reJustISODate).groups)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment