diff --git a/src/core/inputs.ts b/src/core/inputs.ts index 597e882c..0783fb1b 100644 --- a/src/core/inputs.ts +++ b/src/core/inputs.ts @@ -31,6 +31,7 @@ export const anyOf = (...args: New) => MapToCapturedGroupsArr > +export const between = createInput('[\\w-\\w]') export const char = createInput('.') export const word = createInput('\\b\\w+\\b') export const wordChar = createInput('\\w') diff --git a/src/core/internal.ts b/src/core/internal.ts index c72909f2..abf400c0 100644 --- a/src/core/internal.ts +++ b/src/core/internal.ts @@ -60,6 +60,10 @@ export interface Input< max: Max ) => Input, G, C> } + between: ( + first: First, + last: First extends string ? string : number + ) => Input, G, C> /** this defines the entire input so far as a named capture group. You will get type safety when using the resulting RegExp with `String.match()`. Alias for `groupedAs` */ as: ( key: K @@ -117,6 +121,8 @@ export const createInput = < atLeast: (min: number) => createInput(`${wrap(s)}{${min},}`) as any, between: (min: number, max: number) => createInput(`${wrap(s)}{${min},${max}}`) as any, }), + between: (first: string | number, last: string | number) => + createInput(`[${first}-${last}]`) as any, optionally: () => createInput(`${wrap(s)}?`) as any, as: groupedAsFn, groupedAs: groupedAsFn, diff --git a/test/index.test.ts b/test/index.test.ts index 58f88ed3..c3fbe0cf 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -74,6 +74,15 @@ describe('inputs', () => { expect(pattern.toString()).toMatchInlineSnapshot('"test\\\\/thing"') expect(createRegExp(pattern).test('test/thing')).toBeTruthy() }) + it('between', () => { + const letterBetween = exactly('').between('c', 'g') + expect(letterBetween.toString()).toMatchInlineSnapshot('"[c-g]"') + expect(createRegExp(letterBetween).test('abcdefghi')).toBeTruthy() + + const digitBetween = exactly('').between(2, 4) + expect(digitBetween.toString()).toMatchInlineSnapshot('"[2-4]"') + expect(createRegExp(digitBetween).test('1234567')).toBeTruthy() + }) it('times', () => { expect(exactly('test').times.between(1, 3).toString()).toMatchInlineSnapshot('"(?:test){1,3}"') expect(exactly('test').times(4).or('foo').toString()).toMatchInlineSnapshot(