index.js
 1  'use strict';
 2  
 3  var extend = require('extend-shallow');
 4  var safe = require('safe-regex');
 5  
 6  /**
 7   * The main export is a function that takes a `pattern` string and an `options` object.
 8   *
 9   * ```js
10   & var not = require('regex-not');
11   & console.log(not('foo'));
12   & //=> /^(?:(?!^(?:foo)$).)*$/
13   * ```
14   *
15   * @param {String} `pattern`
16   * @param {Object} `options`
17   * @return {RegExp} Converts the given `pattern` to a regex using the specified `options`.
18   * @api public
19   */
20  
21  function toRegex(pattern, options) {
22    return new RegExp(toRegex.create(pattern, options));
23  }
24  
25  /**
26   * Create a regex-compatible string from the given `pattern` and `options`.
27   *
28   * ```js
29   & var not = require('regex-not');
30   & console.log(not.create('foo'));
31   & //=> '^(?:(?!^(?:foo)$).)*$'
32   * ```
33   * @param {String} `pattern`
34   * @param {Object} `options`
35   * @return {String}
36   * @api public
37   */
38  
39  toRegex.create = function(pattern, options) {
40    if (typeof pattern !== 'string') {
41      throw new TypeError('expected a string');
42    }
43  
44    var opts = extend({}, options);
45    if (opts.contains === true) {
46      opts.strictNegate = false;
47    }
48  
49    var open = opts.strictOpen !== false ? '^' : '';
50    var close = opts.strictClose !== false ? '$' : '';
51    var endChar = opts.endChar ? opts.endChar : '+';
52    var str = pattern;
53  
54    if (opts.strictNegate === false) {
55      str = '(?:(?!(?:' + pattern + ')).)' + endChar;
56    } else {
57      str = '(?:(?!^(?:' + pattern + ')$).)' + endChar;
58    }
59  
60    var res = open + str + close;
61    if (opts.safe === true && safe(res) === false) {
62      throw new Error('potentially unsafe regular expression: ' + res);
63    }
64  
65    return res;
66  };
67  
68  /**
69   * Expose `toRegex`
70   */
71  
72  module.exports = toRegex;