Skip to content

Commit

Permalink
add atLeastLazy method (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
CogentRedTester committed Jun 14, 2023
1 parent f1d51ec commit 464d79b
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 0 deletions.
5 changes: 5 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ declare class SuperExpressive {
*/
atLeast(n: number): SuperExpressive;

/**
* Assert that the proceeding element will be matched at least `n` times, but as few times as possible.
*/
atLeastLazy(n: number): SuperExpressive;

/**
* Assert that the proceeding element will be matched somewhere between `x` and `y` times.
*/
Expand Down
15 changes: 15 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const quantifierTable = {
optional: '?',
exactly: times => `{${times}}`,
atLeast: times => `{${times},}`,
atLeastLazy: times => `{${times},}?`,
between: times => `{${times[0]},${times[1]}}`,
betweenLazy: times => `{${times[0]},${times[1]}}?`,
}
Expand Down Expand Up @@ -114,6 +115,7 @@ const t = {
assertNotBehind: deferredType('assertNotBehind', { containsChildren: true }),
exactly: times => deferredType('exactly', { times, containsChild: true }),
atLeast: times => deferredType('atLeast', { times, containsChild: true }),
atLeastLazy: times => deferredType('atLeastLazy', { times, containsChild: true }),
between: (x, y) => deferredType('between', { times: [x, y], containsChild: true }),
betweenLazy: (x, y) => deferredType('betweenLazy', { times: [x, y], containsChild: true }),
zeroOrMore: deferredType('zeroOrMore', { containsChild: true }),
Expand Down Expand Up @@ -334,6 +336,18 @@ class SuperExpressive {
return next;
}

atLeastLazy(n) {
assert(Number.isInteger(n) && n > 0, `n must be a positive integer (got ${n})`);

const next = this[clone]();
const currentFrame = next[getCurrentFrame]();
if (currentFrame.quantifier) {
throw new Error(`cannot quantify regular expression with "atLeastLazy" because it's already being quantified with "${currentFrame.quantifier.type}"`);
}
currentFrame.quantifier = t.atLeastLazy(n);
return next;
}

between(x, y) {
assert(Number.isInteger(x) && x >= 0, `x must be an integer (got ${x})`);
assert(Number.isInteger(y) && y > 0, `y must be an integer greater than 0 (got ${y})`);
Expand Down Expand Up @@ -793,6 +807,7 @@ class SuperExpressive {
case 'betweenLazy':
case 'between':
case 'atLeast':
case 'atLeastLazy':
case 'exactly': {
const inner = SuperExpressive[evaluate](el.value);
const withGroup = el.value.quantifierRequiresGroup
Expand Down
1 change: 1 addition & 0 deletions index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ describe('SuperExpressive', () => {
testRegexEquality('oneOrMoreLazy', /\w+?/, SuperExpressive().oneOrMoreLazy.word);
testRegexEquality('exactly', /\w{4}/, SuperExpressive().exactly(4).word);
testRegexEquality('atLeast', /\w{4,}/, SuperExpressive().atLeast(4).word);
testRegexEquality('atLeastLazy', /\w{4,}?/, SuperExpressive().atLeastLazy(4).word);
testRegexEquality('between', /\w{4,7}/, SuperExpressive().between(4, 7).word);
testRegexEquality('betweenLazy', /\w{4,7}?/, SuperExpressive().betweenLazy(4, 7).word);

Expand Down
14 changes: 14 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
- [.oneOrMoreLazy](#oneOrMoreLazy)
- [.exactly(n)](#exactlyn)
- [.atLeast(n)](#atLeastn)
- [.atLeastLazy(n)](#atLeastLazyn)
- [.between(x, y)](#betweenx-y)
- [.betweenLazy(x, y)](#betweenLazyx-y)
- [.startOfInput](#startOfInput)
Expand Down Expand Up @@ -735,6 +736,19 @@ SuperExpressive()
/\d{5,}/
```

### .atLeastLazy(n)

Assert that the proceeding element will be matched at least `n` times, but as few times as possible.

**Example**
```JavaScript
SuperExpressive()
.atLeastLazy(5).digit
.toRegex();
// ->
/\d{5,}?/
```

### .between(x, y)

Assert that the proceeding element will be matched somewhere between `x` and `y` times.
Expand Down

0 comments on commit 464d79b

Please sign in to comment.