Skip to content

Commit

Permalink
wrap result
Browse files Browse the repository at this point in the history
  • Loading branch information
jonschlinkert committed Jan 17, 2019
1 parent cd04d2c commit f7ce5ac
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 81 deletions.
18 changes: 9 additions & 9 deletions .verb.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ This libary generates the `source` string to be passed to `new RegExp()` for mat
**Example**

```js
var toRegexRange = require('{%= name %}');
var regex = new RegExp(toRegexRange('15', '95'));
const toRegexRange = require('{%= name %}');
const regex = new RegExp(toRegexRange('15', '95'));
```

A string is returned so that you can do whatever you need with it before passing it to `new RegExp()` (like adding `^` or `$` boundaries, defining flags, or combining it another string).
Expand Down Expand Up @@ -66,16 +66,16 @@ Generated regular expressions are highly optimized:
Add this library to your javascript application with the following line of code

```js
var toRegexRange = require('{%= name %}');
const toRegexRange = require('{%= name %}');
```

The main export is a function that takes two integers: the `min` value and `max` value (formatted as strings or numbers).

```js
var source = toRegexRange('15', '95');
const source = toRegexRange('15', '95');
//=> 1[5-9]|[2-8][0-9]|9[0-5]

var re = new RegExp('^' + source + '$');
const re = new RegExp('^' + source + '$');
console.log(re.test('14')); //=> false
console.log(re.test('50')); //=> true
console.log(re.test('94')); //=> true
Expand All @@ -96,7 +96,7 @@ Wrap the returned value in parentheses when there is more than one regex conditi
console.log(toRegexRange('-10', '10'));
//=> -[1-9]|-?10|[0-9]

console.log(toRegexRange('-10', '10', {capture: true}));
console.log(toRegexRange('-10', '10', { capture: true }));
//=> (-[1-9]|-?10|[0-9])
```

Expand All @@ -112,7 +112,7 @@ Use the regex shorthand for `[0-9]`:
console.log(toRegexRange('0', '999999'));
//=> [0-9]|[1-9][0-9]{1,5}

console.log(toRegexRange('0', '999999', {shorthand: true}));
console.log(toRegexRange('0', '999999', { shorthand: true }));
//=> \d|[1-9]\d{1,5}
```

Expand All @@ -138,7 +138,7 @@ console.log(toRegexRange('-001', '100', {relaxZeros: false}));
Consider the following.

```js
var regex = toRegexRange('-001', '100');
const regex = toRegexRange('-001', '100');
```

_Note that `-001` and `100` are both three digits long_.
Expand Down Expand Up @@ -193,4 +193,4 @@ Repeating ranges are now grouped using quantifiers. rocessing time is roughly th

## Attribution

Inspired by the python library [range-regex](https://github.com/dimka665/range-regex).
Inspired by the python library [range-regex](https://github.com/dimka665/range-regex).
4 changes: 2 additions & 2 deletions examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const time = new Time();
function toRange(min, max) {
let key = 'to-range' + min + max;
time.start(key);
let str = toRegexRange(min, max);
let str = toRegexRange(min, max, { wrap: false });
return [
'',
'`toRegexRange(\'' + min + ', ' + max + '\')`',
Expand Down Expand Up @@ -59,7 +59,7 @@ let examples = [
rows.push(toRange.apply(null, args));
});

let text = table(rows, {hsep: ' | '});
let text = table(rows, { hsep: ' | ' });
console.log(text);

/**
Expand Down
13 changes: 9 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*!
* to-regex-range <https://github.com/micromatch/to-regex-range>
*
* Copyright (c) 2015-2018, present, Jon Schlinkert.
* Copyright (c) 2015-present, Jon Schlinkert.
* Released under the MIT License.
*/

Expand Down Expand Up @@ -39,7 +39,10 @@ function toRegexRange(min, max, options) {
if (options.capture) {
return '(' + result + ')';
}
return result;
if (options.wrap === false) {
return result;
}
return '(?:' + result + ')';
}

let isPadded = padding(min) || padding(max);
Expand Down Expand Up @@ -67,8 +70,10 @@ function toRegexRange(min, max, options) {
tok.positives = positives;
tok.result = siftPatterns(negatives, positives, options);

if (options.capture && (positives.length + negatives.length) > 1) {
if (options.capture) {
tok.result = '(' + tok.result + ')';
} else if (options.wrap !== false && positives.length + negatives.length > 1) {
tok.result = '(?:' + tok.result + ')';
}

toRegexRange.cache[key] = tok;
Expand Down Expand Up @@ -219,7 +224,7 @@ function filterPatterns(arr, comparison, prefix, intersection, options) {
}

/**
* Zip strings (`for in` can be used on string characters)
* Zip strings
*/

function zip(a, b) {
Expand Down
37 changes: 15 additions & 22 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
"is-number": "^7.0.0"
},
"devDependencies": {
"fill-range": "^5.0.0",
"gulp-format-md": "^1.0.0",
"fill-range": "^6.0.0",
"gulp-format-md": "^2.0.0",
"mocha": "^5.2.0",
"text-table": "^0.2.0",
"time-diff": "^0.3.1"
Expand Down Expand Up @@ -56,17 +56,8 @@
"year"
],
"verb": {
"related": {
"list": [
"expand-range",
"fill-range",
"micromatch",
"repeat-element",
"repeat-string"
]
},
"toc": false,
"layout": "default",
"toc": false,
"tasks": [
"readme"
],
Expand All @@ -76,15 +67,17 @@
"lint": {
"reflinks": true
},
"helpers": [
"./examples.js"
],
"reflinks": [
"micromatch",
"0-5",
"0-9",
"1-5",
"1-9"
]
"helpers": {
"examples": "./examples.js"
},
"related": {
"list": [
"expand-range",
"fill-range",
"micromatch",
"repeat-element",
"repeat-string"
]
}
}
}
106 changes: 62 additions & 44 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ function inRange(min, max, num) {

describe('to-regex-range', function() {
after(function() {
let num = (+(+(count).toFixed(2))).toLocaleString();
let num = (+(+count.toFixed(2))).toLocaleString();
console.log();
console.log(' ', num, 'values tested');
});
Expand All @@ -95,11 +95,29 @@ describe('to-regex-range', function() {
it('should throw an error when the second arg is invalid:', function() {
assert.throws(() => toRange(1, {}), /expected/);
});

it('should match the given numbers', function() {
let oneFifty = new RegExp('^' + toRange(1, 150) + '$');
assert(oneFifty.test('125'));
assert(!oneFifty.test('0'));
assert(oneFifty.test('1'));
assert(oneFifty.test('126'));
assert(oneFifty.test('150'));
assert(!oneFifty.test('151'));

let oneTwentyFive = new RegExp('^' + toRange(1, 125) + '$');
assert(oneTwentyFive.test('125'));
assert(!oneTwentyFive.test('0'));
assert(oneTwentyFive.test('1'));
assert(!oneTwentyFive.test('126'));
assert(!oneTwentyFive.test('150'));
assert(!oneTwentyFive.test('151'));
});
});

describe('minimum / maximum', function() {
it('should reverse `min/max` when the min is larger than the max:', function() {
assert.strictEqual(toRange(55, 10), '1[0-9]|[2-4][0-9]|5[0-5]');
assert.strictEqual(toRange(55, 10), '(?:1[0-9]|[2-4][0-9]|5[0-5])');
});
});

Expand All @@ -118,74 +136,74 @@ describe('to-regex-range', function() {

it('should support strings:', function() {
assert.strictEqual(toRange('1', '5'), '[1-5]');
assert.strictEqual(toRange('10', '50'), '1[0-9]|[2-4][0-9]|50');
assert.strictEqual(toRange('10', '50'), '(?:1[0-9]|[2-4][0-9]|50)');
});

it('should support padded ranges:', function() {
assert.strictEqual(toRange('001', '005'), '0{2}[1-5]');
assert.strictEqual(toRange('01', '05'), '0[1-5]');
assert.strictEqual(toRange('001', '100'), '0{2}[1-9]|0[1-9][0-9]|100');
assert.strictEqual(toRange('0001', '1000'), '0{3}[1-9]|0{2}[1-9][0-9]|0[1-9][0-9]{2}|1000');
assert.strictEqual(toRange('001', '100'), '(?:0{2}[1-9]|0[1-9][0-9]|100)');
assert.strictEqual(toRange('0001', '1000'), '(?:0{3}[1-9]|0{2}[1-9][0-9]|0[1-9][0-9]{2}|1000)');
});

it('should work when padding is imbalanced:', function() {
assert.strictEqual(toRange('001', '105'), '0{2}[1-9]|0[1-9][0-9]|10[0-5]');
assert.strictEqual(toRange('01', '105'), '0{2}[1-9]|0[1-9][0-9]|10[0-5]');
assert.strictEqual(toRange('010', '105'), '01[0-9]|0[2-9][0-9]|10[0-5]');
assert.strictEqual(toRange('010', '1005'), '0{2}1[0-9]|0{2}[2-9][0-9]|0[1-9][0-9]{2}|100[0-5]');
assert.strictEqual(toRange('001', '105'), '(?:0{2}[1-9]|0[1-9][0-9]|10[0-5])');
assert.strictEqual(toRange('01', '105'), '(?:0{2}[1-9]|0[1-9][0-9]|10[0-5])');
assert.strictEqual(toRange('010', '105'), '(?:01[0-9]|0[2-9][0-9]|10[0-5])');
assert.strictEqual(toRange('010', '1005'), '(?:0{2}1[0-9]|0{2}[2-9][0-9]|0[1-9][0-9]{2}|100[0-5])');
assert.strictEqual(toRange('0001', '1000'), toRange('001', '1000'));
assert.strictEqual(toRange('0001', '1000'), toRange('01', '1000'));
});

it('should generate regex strings for negative patterns', function() {
assert.strictEqual(toRange(-1, 0), '-1|0');
assert.strictEqual(toRange(-1, 1), '-1|[01]');
assert.strictEqual(toRange(-1, 0), '(?:-1|0)');
assert.strictEqual(toRange(-1, 1), '(?:-1|[01])');
assert.strictEqual(toRange(-4, -2), '-[2-4]');
assert.strictEqual(toRange(-3, 1), '-[1-3]|[01]');
assert.strictEqual(toRange(-2, 0), '-[12]|0');
assert.strictEqual(toRange(-1, 3), '-1|[0-3]');
assert.strictEqual(toRange(-3, 1), '(?:-[1-3]|[01])');
assert.strictEqual(toRange(-2, 0), '(?:-[12]|0)');
assert.strictEqual(toRange(-1, 3), '(?:-1|[0-3])');
matchRange(-1, -1, '-1', [-1], [-2, 0, 1]);
matchRange(-1, -10, '-[1-9]|-10', [-1, -5, -10], [-11, 0]);
matchRange(-1, 3, '-1|[0-3]', [-1, 0, 1, 2, 3], [-2, 4]);
matchRange(-1, -10, '(?:-[1-9]|-10)', [-1, -5, -10], [-11, 0]);
matchRange(-1, 3, '(?:-1|[0-3])', [-1, 0, 1, 2, 3], [-2, 4]);
});

it('should wrap patterns when options.capture is true', function() {
assert.strictEqual(toRange(-1, 0, {capture: true}), '(-1|0)');
assert.strictEqual(toRange(-1, 1, {capture: true}), '(-1|[01])');
assert.strictEqual(toRange(-4, -2, {capture: true}), '-[2-4]');
assert.strictEqual(toRange(-3, 1, {capture: true}), '(-[1-3]|[01])');
assert.strictEqual(toRange(-2, 0, {capture: true}), '(-[12]|0)');
assert.strictEqual(toRange(-1, 3, {capture: true}), '(-1|[0-3])');
assert.strictEqual(toRange(-1, 0, { capture: true }), '(-1|0)');
assert.strictEqual(toRange(-1, 1, { capture: true }), '(-1|[01])');
assert.strictEqual(toRange(-4, -2, { capture: true }), '(-[2-4])');
assert.strictEqual(toRange(-3, 1, { capture: true }), '(-[1-3]|[01])');
assert.strictEqual(toRange(-2, 0, { capture: true }), '(-[12]|0)');
assert.strictEqual(toRange(-1, 3, { capture: true }), '(-1|[0-3])');
});

it('should generate regex strings for positive patterns', function() {
assert.strictEqual(toRange(1, 1), '1');
assert.strictEqual(toRange(0, 1), '0|1');
assert.strictEqual(toRange(0, 1), '(?:0|1)');
assert.strictEqual(toRange(0, 2), '[0-2]');
assert.strictEqual(toRange(65666, 65667), '65666|65667');
assert.strictEqual(toRange(12, 3456), '1[2-9]|[2-9][0-9]|[1-9][0-9]{2}|[12][0-9]{3}|3[0-3][0-9]{2}|34[0-4][0-9]|345[0-6]');
assert.strictEqual(toRange(1, 3456), '[1-9]|[1-9][0-9]{1,2}|[12][0-9]{3}|3[0-3][0-9]{2}|34[0-4][0-9]|345[0-6]');
assert.strictEqual(toRange(1, 10), '[1-9]|10');
assert.strictEqual(toRange(1, 19), '[1-9]|1[0-9]');
assert.strictEqual(toRange(1, 99), '[1-9]|[1-9][0-9]');
assert.strictEqual(toRange(1, 100), '[1-9]|[1-9][0-9]|100');
assert.strictEqual(toRange(1, 1000), '[1-9]|[1-9][0-9]{1,2}|1000');
assert.strictEqual(toRange(1, 10000), '[1-9]|[1-9][0-9]{1,3}|10000');
assert.strictEqual(toRange(1, 100000), '[1-9]|[1-9][0-9]{1,4}|100000');
assert.strictEqual(toRange(1, 9999999), '[1-9]|[1-9][0-9]{1,6}');
assert.strictEqual(toRange(99, 100000), '99|[1-9][0-9]{2,4}|100000');

matchRange(99, 100000, '99|[1-9][0-9]{2,4}|100000', [99, 999, 989, 100, 9999, 9899, 10009, 10999, 100000], [0, 9, 100001, 100009]);
assert.strictEqual(toRange(65666, 65667), '(?:65666|65667)');
assert.strictEqual(toRange(12, 3456), '(?:1[2-9]|[2-9][0-9]|[1-9][0-9]{2}|[12][0-9]{3}|3[0-3][0-9]{2}|34[0-4][0-9]|345[0-6])');
assert.strictEqual(toRange(1, 3456), '(?:[1-9]|[1-9][0-9]{1,2}|[12][0-9]{3}|3[0-3][0-9]{2}|34[0-4][0-9]|345[0-6])');
assert.strictEqual(toRange(1, 10), '(?:[1-9]|10)');
assert.strictEqual(toRange(1, 19), '(?:[1-9]|1[0-9])');
assert.strictEqual(toRange(1, 99), '(?:[1-9]|[1-9][0-9])');
assert.strictEqual(toRange(1, 100), '(?:[1-9]|[1-9][0-9]|100)');
assert.strictEqual(toRange(1, 1000), '(?:[1-9]|[1-9][0-9]{1,2}|1000)');
assert.strictEqual(toRange(1, 10000), '(?:[1-9]|[1-9][0-9]{1,3}|10000)');
assert.strictEqual(toRange(1, 100000), '(?:[1-9]|[1-9][0-9]{1,4}|100000)');
assert.strictEqual(toRange(1, 9999999), '(?:[1-9]|[1-9][0-9]{1,6})');
assert.strictEqual(toRange(99, 100000), '(?:99|[1-9][0-9]{2,4}|100000)');

matchRange(99, 100000, '(?:99|[1-9][0-9]{2,4}|100000)', [99, 999, 989, 100, 9999, 9899, 10009, 10999, 100000], [0, 9, 100001, 100009]);
});

it('should optimize regexes', function() {
assert.strictEqual(toRange(-9, 9), '-[1-9]|[0-9]');
assert.strictEqual(toRange(-19, 19), '-[1-9]|-?1[0-9]|[0-9]');
assert.strictEqual(toRange(-29, 29), '-[1-9]|-?[12][0-9]|[0-9]');
assert.strictEqual(toRange(-99, 99), '-[1-9]|-?[1-9][0-9]|[0-9]');
assert.strictEqual(toRange(-999, 999), '-[1-9]|-?[1-9][0-9]{1,2}|[0-9]');
assert.strictEqual(toRange(-9999, 9999), '-[1-9]|-?[1-9][0-9]{1,3}|[0-9]');
assert.strictEqual(toRange(-99999, 99999), '-[1-9]|-?[1-9][0-9]{1,4}|[0-9]');
assert.strictEqual(toRange(-9, 9), '(?:-[1-9]|[0-9])');
assert.strictEqual(toRange(-19, 19), '(?:-[1-9]|-?1[0-9]|[0-9])');
assert.strictEqual(toRange(-29, 29), '(?:-[1-9]|-?[12][0-9]|[0-9])');
assert.strictEqual(toRange(-99, 99), '(?:-[1-9]|-?[1-9][0-9]|[0-9])');
assert.strictEqual(toRange(-999, 999), '(?:-[1-9]|-?[1-9][0-9]{1,2}|[0-9])');
assert.strictEqual(toRange(-9999, 9999), '(?:-[1-9]|-?[1-9][0-9]{1,3}|[0-9])');
assert.strictEqual(toRange(-99999, 99999), '(?:-[1-9]|-?[1-9][0-9]{1,4}|[0-9])');
});
});

Expand Down

0 comments on commit f7ce5ac

Please sign in to comment.