From ad61ab1063426f1a9041a120d7d469962e260544 Mon Sep 17 00:00:00 2001 From: Jon Abrams <jon@jonabrams.com> Date: Fri, 26 Jun 2015 00:41:33 -0700 Subject: [PATCH] Add regex flags and newlines --- readme.md | 22 +++++++++++++++++++--- test.js | 17 ++++++++++++++++- xeger.js | 25 +++++++++++++++++++++---- 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/readme.md b/readme.md index ff14221..a5b1c59 100644 --- a/readme.md +++ b/readme.md @@ -63,7 +63,7 @@ matched: ## API -### xeger([function]) +### xeger([function], [options]) Call this to start the construction of the regex, passing in a callback function. It returns a RegExp object. @@ -71,6 +71,12 @@ Use the rest of the functions in this section (the *rule* functions) to construc The callback function will be called with one parameter, the xeger object. The rest of the functions here should be called on the xeger object. The callback is also called with the xeger object assigned to `this`. +The options object passed here is different from the options object used in the rest of the API. This one takes the following keys: + +- **global**: [boolean] - Will attempt to match the regex multiple times. +- **multiline**: [boolean] - Will attempt to match the regex multiple times. +- **insensitive**: [boolean] - Case insensitive matching. + ### x.literal([string], [options]) Matches the exact string passed in. `x.literal` will escape any non-alpha numeric character. @@ -122,13 +128,13 @@ xeger(function (x) { ### x.to() -Used to create the '-' inside *any* and *not* functions. +Used to create the '-' inside *any* and *not* functions (see examples for *any* and *not*). If you were to just do `x.any('A-Z')` the `-` would be escaped: `/[A\-Z]/` ### x.alphanumeric([options]) -Matches any single alpha-numeric character (i.e. letters and numbers). +Matches any single alpha-numeric character (includes letters, numbers, and the underscore). ```javascript xeger(function (x) { @@ -156,6 +162,16 @@ xeger(function (x) { }); /* returns /\s/ */ ``` +### x.newline([options]) + +Matches a newline character + +```javascript +xeger(function (x) { + x.newline(); +}); /* returns /\n/ */ +``` + ### x.start() Matches the start of the string. diff --git a/test.js b/test.js index e8337d3..22dea1f 100644 --- a/test.js +++ b/test.js @@ -8,9 +8,24 @@ describe('xeger', function () { r.literal('hello'); r.alphanumeric(); r.number(); + r.newline(); r.end(); }); - assert.equal(regex.toString(), '/^hello\\w\\d$/'); + assert.equal(regex.toString(), '/^hello\\w\\d\\n$/'); + }); + + describe('flags', function () { + var regex = xeger(function (r) { + r.literal('hi'); + }, { + global: true, + multiline: true, + insensitive: true + }); + + it('adds flags', function () { + assert.equal(regex.toString(), '/hi/gim'); + }); }); describe('some options', function () { diff --git a/xeger.js b/xeger.js index af56236..4c73d73 100644 --- a/xeger.js +++ b/xeger.js @@ -1,12 +1,24 @@ -module.exports = function (cb) { - var r = new Xeger(cb); +module.exports = function (cb, options) { + var r = new Xeger(cb, options); return r.regex(); }; -var Xeger = function (cb) { +var Xeger = function (cb, options) { + options = options || {}; this.regexStr = ''; + this.flags = ''; + + if (options.multiline) { + this.flags += 'm'; + } + if (options.global) { + this.flags += 'g'; + } + if (options.insensitive) { + this.flags += 'i'; + } cb.call(this, this); }; @@ -37,6 +49,11 @@ Xeger.prototype.number = function (options) { this.addOptions(options); }; +Xeger.prototype.newline = function (options) { + this.add('\\n'); + this.addOptions(options); +}; + Xeger.prototype.start = function () { this.add('^'); }; @@ -89,7 +106,7 @@ Xeger.prototype.group = function (cb, options) { /* Private */ Xeger.prototype.regex = function () { - return new RegExp(this.regexStr); + return new RegExp(this.regexStr, this.flags); }; Xeger.prototype.addOptions = function (options) {