callstack/ts-regex-builder

[Bug] Can't escaped a period ('.') in an anyOf call

PaulJPhilp opened this issue · 4 comments

Describe the bug
Due to the missing constructor (issue #74) I tried to use anyOf('.') in the following:

const period = anyOf('.')
const hostname = [host, optional(repeat([period, host], { min: 1, max: 255 }))];

The result was an unescaped period ('.') (match any character) in the regex. This caused a number of weird issues
which kept me company all weekend.

I then tried an escaped period in the anyOf:

const period = anyOf('\.')
const hostname = [host, optional(repeat([period, host], { min: 1, max: 255 }))];

There was no change, the result was an unescaped period.

To Reproduce

import { buildRegExp, anyOf } from '..';

const period = anyOf('.');
const regex = buildRegExp(period);
console.log(regex.source); 
console.log(regex);

const escapedPeriod = anyOf('\.');
const escapedRegex = buildRegExp(escapedPeriod);
console.log(escapedRegex.source);
console.log(escapedRegex);

test('`plain period`', () => {
  expect(regex.source).toBe('.');
  expect(regex).toEqualRegex(RegExp(/./));
  expect(regex).toMatchString('.');
  expect(regex).not.toMatchString('a');
});

test('`escapedRegex`', () => {
  expect(escapedRegex.source).toBe('.');
  expect(escapedRegex).toEqualRegex(RegExp(/\./));
  expect(escapedRegex).toMatchString('.');
  expect(escapedRegex).toMatchString('a');
});

Expected behavior
I expected to match the period in hostnames (i.e. www.google.com).

Screenshots
If applicable, add screenshots to help explain your problem.

Package version
ts-regex-builder: ???

Good catch, TS regex optimizes single characters classes, which causes . to be come any. Simple mitigation would be to avoid using anyOf("."), and just use ., there is no need to add anyOf for single character.

Either way, I will issue a bug fix for that.

Fixed by #76

Resolved in v1.4.0 🎉