/regex-fun

Write maintainable regular expressions

Primary LanguageJavaScript

Build regular expressions with functions.

Quick example

const anyGreeting = either('howdy', 'hi', 'hey')
const regex = combine(anyGreeting, optional(','), ' ', capture(/\w+/))
regex // => /(?:howdy|hi|hey)(?:,)? (\w+)/
'hey bub'.match(regex)[1] // => 'bub'

API

Functions return a regular expression without flags. If you want any flags, call the flags function last.

Regular expression input may be either a RegExp or a string. If it is a string, regex characters will be escaped - anyNumber('a+') will match any number of occurrences of a+ in a string (/a\+*/).

const {
	combine,
	flags,
	capture,
	either,

	anyNumber,
	oneOrMore,
	optional,
	exactly,
	atLeast,
	between,

	anyNumberNonGreedy,
	oneOrMoreNonGreedy,
	optionalNonGreedy,
	exactlyNonGreedy,
	atLeastNonGreedy,
	betweenNonGreedy,

} = require('regex-fun')

combine(...input)

combine(/sup/, 'd*g') // => /supd\*g/

either(...input)

either(/this/, /that/, 'other thing') // => /(?:this|that|other thing)/

capture(...input)

capture(/\w+/, either('this', 'that')) // => /(\w+(?:this|that))/

flags(flags, ...input)

flags('gm', /HOWDY/i) // => /HOWDY/gm

Greedy matching

anyNumber(...input)

anyNumber('wat') // => /(?:wat)*/

oneOrMore(...input)

oneOrMore('wat') // => /(?:wat)+/

optional(...input)

optional('wat') // => /(?:wat)?/

exactly(n, ...input)

exactly(2, 'wat') // => /(?:wat){2}/

atLeast(n, ...input)

atLeast(3, 'wat') // => /(?:wat){3,}/

between(n, m, ...input)

between(4, 5, 'wat') // => /(?:wat){4,5}/

Non-greedy matching

anyNumberNonGreedy(...input)

anyNumberNonGreedy('wat') // => /(?:wat)*?/

oneOrMoreNonGreedy(...input)

oneOrMoreNonGreedy('wat') // => /(?:wat)+?/

optionalNonGreedy(...input)

optionalNonGreedy('wat') // => /(?:wat)??/

exactlyNonGreedy(n, ...input)

exactlyNonGreedy(2, 'wat') // => /(?:wat){2}?/

atLeastNonGreedy(n, ...input)

atLeastNonGreedy(3, 'wat') // => /(?:wat){3,}?/

betweenNonGreedy(n, m, ...input)

betweenNonGreedy(4, 5, 'wat') // => /(?:wat){4,5}?/

Put it all together and you can do some cool stuff

This example is from verse-reference-regex, which finds and parses Bible verse ranges like "Revelation 13:5-6":

const requireVerse = true

const number = /(\d+)/
const numberAndOptionalLetter = /(\d+)([a-z])?/
const colonVerse = combine(':', numberAndOptionalLetter)
const chapterAndVerse = combine(number, requireVerse ? colonVerse : optional(colonVerse))

const secondHalfOfRange = combine(
	'-',
	either(
		/([a-z])/,
		/(\d+)([a-z])/,
		chapterAndVerse,
		numberAndOptionalLetter
	)
)
const range = combine(chapterAndVerse, optional(secondHalfOfRange))

const regexThatMatchesVerses = combine(
	capture(either(...bookNames, ...abbreviations)),
	' ',
	range
)

If you see a function missing, open a pull request, otherwise I'll add new functions as I need them.

License

WTFPL