import { createRegExp, exactly } from 'magic-regexp'const regExp = createRegExp(exactly('foo/test.js').after('bar/'))console.log(regExp)// /(?<=bar\/)foo\/test\.js/
createRegExp
Every pattern you create with the library should be wrapped in createRegExp
, which enables the build-time transform.
The first argument is either a string to match exactly, or an input pattern built up using helpers from magic-regexp
. It also takes a second argument, which is an array of flags or flags string.
import { createRegExp, global, multiline, exactly } from 'magic-regexp'createRegExp(exactly('foo').or('bar'))createRegExp('string-to-match', [global, multiline])// you can also pass flags directly as strings or SetscreateRegExp('string-to-match', ['g', 'm'])
magic-regexp
assume that input that is passed should be escaped - so no special RegExp characters apply. So createRegExp('foo?\d')
will not match food3
but only foo?\d
exactly.Creating inputs
There are a range of helpers that can be used to activate pattern matching, and they can be chained. Each one of these returns an object of type Input
that can be passed directly to new RegExp
, createRegExp
, to another helper or chained to produce more complex patterns.
charIn , charNotIn | this matches or doesn't match any character in the string provided. |
anyOf | this takes an array of inputs and matches any of them. |
char , word , wordChar , wordBoundary , digit , whitespace , letter , letter.lowercase , letter.uppercase , tab , linefeed and carriageReturn | these are helpers for specific RegExp characters. |
not | this can prefix word , wordChar , wordBoundary , digit , whitespace , letter , letter.lowercase , letter.uppercase , tab , linefeed or carriageReturn . For example createRegExp(not.letter) . |
maybe | equivalent to ? - this marks the input as optional. |
oneOrMore | Equivalent to + - this marks the input as repeatable, any number of times but at least once. |
exactly | This escapes a string input to match it exactly. |
Chaining inputs
All of the helpers above return an object of type Input
that can be chained with the following helpers:
and | this adds a new pattern to the current input, or you can use and.referenceTo(groupName) to adds a new pattern referencing to a named group. |
or | this provides an alternative to the current input. |
after , before , notAfter and notBefore | these activate positive/negative lookahead/lookbehinds. Make sure to check browser support as not all browsers support lookbehinds (notably Safari). |
times | this is a function you can call directly to repeat the previous pattern an exact number of times, or you can use times.between(min, max) to specify a range, times.atLeast(x) to indicate it must repeat at least x times, times.atMost(x) to indicate it must repeat at most x times or times.any() to indicate it can repeat any number of times, including none. |
optionally | this is a function you can call to mark the current input as optional. |
as | alias for groupedAs |
groupedAs | this defines the entire input so far as a named capture group. You will get type safety when using the resulting RegExp with String.match() . |
grouped | this defines the entire input so far as an anonymous group. |
at | this allows you to match beginning/ends of lines with at.lineStart() and at.lineEnd() . |
anyOf
, maybe
, oneOrMore
, and chaining input helpers such as or
, times(.between/atLeast/any)
, or optionally
will wrap the input in a non-capturing group with (?:)
. You can use chaining input helper grouped
after any Input
type to capture it as an anonymous group.Debugging
When using magic-regexp
, a TypeScript generic is generated for you that should show the RegExp that you are constructing, as you go.
This is true not just for the final RegExp, but also for the pieces you create along the way.
So, for example:
import { exactly } from 'magic-regexp'exactly('test.mjs')// (alias) exactly<"test.mjs">(input: "test.mjs"): Input<"test\\.mjs", never>exactly('test.mjs').or('something.else')// (property) Input<"test\\.mjs", never>.or: <"something.else">(input: "something.else") => Input<"(?:test\\.mjs|something\\.else)", never>
Each function, if you hover over it, shows what's going in, and what's coming out by way of regular expression
You can also call .toString()
on any input to see the same information at runtime.