regular expressions for humans
npm install regularity[![Build Status][travis-image]][travis-url]
[![Coverage Status][coveralls-image]][coveralls-url]
[![Code Climate][codeclimate-image]][codeclimate-url]
[![NPM][nodeico-image]][nodeico-url]
regularity is a friendly regular expression builder
for Node.
It is a JavaScript port
of the very fine regularity Ruby gem.
Regular expressions are a powerful way
of matching patterns against text,
but too often they are _write once, read never_.
After all, who wants to try and decipher
``javascript`
/^(?:[0-9]){3}-(?:[A-Za-z]){2}(?:#)?(?:a|b)(?:a){2,4}\$$/i
when you could express it as
`javascript
var Regularity = require('regularity');
var regularity = new Regularity();
var myRegexp = regularity
.startWith(3, 'digits')
.then('-')
.then(2, 'letters')
.maybe('#')
.oneOf('a', 'b')
.between([2, 4], 'a')
.endWith('$')
.insensitive()
.done();
`
While taking up a bit more space,
regular expressions created using regularity
are much more readable than their cryptic counterparts.
But they are still native regular expressions!
To get regularity,
you need to have npm installed.
It should have been installed
along with Node.
Once you have it, just run
``
$ npm install regularity
in your terminal,
and it should promptly download
into the current folder.
When you require regularity,
all you get is a constructor function.
To start building a regular expression,
you should instantiate an object using new,
as demonstrated above,
and then call
any of the methods it provides
with the proper arguments.
When you are done building the regular expression,
tell regularity so by calling done.
This call will return a native [RegExp][regexp-mdn]
implementing the pattern which you described
using the methods of the regularity object,
which you can then use
for your own purposes.
Notice that you should probably use
one new regularity instance
for each regular expression
that you want to build.
If you keep calling methods
on an existing regularity instance,
you will be reusing
the declarations you made on that object before.
regularity instances expose a set of methods
(the _DSL methods_)
which allow you to declaratively build
the regular expression you want.
They all return this,
so they are chainable.
Notice that the order in which you call these methods
determines the order in which the pattern is assembled.
All _DSL methods_ accept at least
one of the following signatures:
either an _unnumbered constraint_,
which is expected to be a single string,
such as then('xyz'),atLeast(2, 'ab')
or a _numbered constraint_,
composed by a count and a pattern,
such as .
In addition, the following _special identifers_
are supported as a shorthand
for some common patterns:
`javascript`
'digit' : '[0-9]'
'lowercase' : '[a-z]'
'uppercase' : '[A-Z]'
'letter' : '[A-Za-z]'
'alphanumeric' : '[A-Za-z0-9]'
'whitespace' : '\s'
'space' : ' '
'tab' : '\t'
_Special identifiers_ may be pluralized,
and regularity will still understand them.
This allows you
to write more meaningful declarations,
because then(2, 'letters') worksthen(1, 'letter')
in addition to .
The following is a more detailed explanation
of all the _DSL methods_ and their signatures.
Should you have any doubts,
please refer to the spec,
where you can find examples
of all the supported use cases.
Bear in mind that, in what follows,
pattern stands for any string,n
which might or might not be
any of the _special identifiers_,
and which might include characters
which need escaping (you don't need
to escape them yourself, as regularity
will take care of that),
and stands for any positive integer1
(that is, any integer
greater than or equal to ).n
Where is optional[n,]
(denoted by in the signature),1
passing as nn
is equivalent to not passing at all.
- [startWith([n,] pattern)](#startWith):
Require that pattern occurn
exactly times
at the beginning of the input.
This method may be called only once.
- [append([n,] pattern)](#append):
Require that pattern occurn
exactly times
after what has been declared so far
and before anything that is declared afterwards.
- [then([n,] pattern)](#then):
This is just an alias for append.
- [endWith([n,] pattern)](#endWith):
Require that pattern occurn
exactly times
at the end of the input.
This method may be called only once.
- maybe(pattern):
Require that pattern occur
either one or zero times.
- [oneOf(firstPattern[, secondPattern[, ...]])](#oneOf):
Require that at least
one of the passed patterns occur.
- between(range, pattern):
Require that pattern occurrange[0]
a number of consecutive times
between and range[1], both included.range
is expected to be an array
containing two positive integers.
- zeroOrMore(pattern):
Require that pattern occur
any number of consecutive times,
including zero times.
- oneOrMore(pattern):
Require that pattern occur
consecutively at least once.
- atLeast(n, pattern):
Require that pattern occurn
consecutively at least times.n
Typically, here should be greater than 11
(if you want it to be exactly , you should use oneOrMore).
- atMost(n, pattern):
Require that pattern occurn
consecutively at most times.n
Typically, here should be greater than 11
(if you want it to be exactly , you should use maybe).
Besides the _DSL methods_, regularity instances
also expose the following methods:
- insensitive():
Specify that the regular expression
mustn't distinguish
between uppercacase and lowercase letters.
- global():
Specify that the regular expression
must match against all possible matches in the string
(instead of matching just the first,
which is the default behaviour).
- multiline():
Specify that the string
against which the [RegExp][regexp-mdn] is to be matched
may span multiple lines.
- done():
Return the native [RegExp][regexp-mdn] object
representing the pattern which you described
by means of the previous calls
on that regularity instance.
- regexp():
This is just an alias for done.
Original idea and Ruby
implementation
are by Andrew Berls.
If you are unsure about the [RegExp][regexp-mdn]regulex
you just built,
is a great tool which will draw you
a fancy _railroad diagram_ of it.
This project is licensed under the
MIT License.
For more details, see the LICENSE` file
at the root of the repository.
[travis-image]: https://travis-ci.org/angelsanz/regularity.svg?branch=master
[travis-url]: https://travis-ci.org/angelsanz/regularity
[coveralls-image]: https://coveralls.io/repos/angelsanz/regularity/badge.svg?branch=master
[coveralls-url]: https://coveralls.io/r/angelsanz/regularity?branch=master
[codeclimate-image]: https://codeclimate.com/github/angelsanz/regularity/badges/gpa.svg
[codeclimate-url]: https://codeclimate.com/github/angelsanz/regularity
[nodeico-image]: https://nodei.co/npm/regularity.png?downloads=true&stars=true
[nodeico-url]: https://nodei.co/npm/regularity/
[regexp-mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp