Skip to content

Instantly share code, notes, and snippets.

@mdjastrzebski
Last active December 4, 2023 21:29
Show Gist options
  • Save mdjastrzebski/544b4014b166d9292a8162cef00cc9ce to your computer and use it in GitHub Desktop.
Save mdjastrzebski/544b4014b166d9292a8162cef00cc9ce to your computer and use it in GitHub Desktop.
Swift Regex for TypeScript
// ref: https://developer.apple.com/documentation/regexbuilder
type RegexComponent = string | RegexQuantifier;
type RegexQuantifier = OneOrMore | Optionally;
type OneOrMore = {
type: 'oneOrMore';
children: RegexComponent[];
};
function oneOrMore(...children: RegexComponent[]): OneOrMore {
return {
type: 'oneOrMore',
children,
};
}
type Optionally = {
type: 'optionally';
children: RegexComponent[];
};
function optionally(...children: RegexComponent[]): Optionally {
return {
type: 'optionally',
children,
};
}
function compile(...children: RegexComponent[]): string {
return children.map((c) => compileSingle(c)).join('');
}
function compileSingle(component: RegexComponent): string {
if (typeof component === 'string') {
return component;
}
const { type, children } = component;
if (type === 'oneOrMore') {
return `${wrapGroup(compile(...children))}+`;
}
if (type === 'optionally') {
return `${wrapGroup(compile(...children))}?`;
}
throw new Error(`Unknown component ${component}`);
}
function wrapGroup(input: string): string {
return input.length === 1 ? input : `(${input})`;
}
function regex(...children: RegexComponent[]): RegExp {
const pattern = compile(...children);
return new RegExp(pattern);
}
test('basic quantifies', () => {
expect(compile('a')).toEqual('a');
expect(compile('a', 'b')).toEqual('ab');
expect(compile(oneOrMore('a'))).toEqual('a+');
expect(compile(optionally('a'))).toEqual('a?');
expect(compile('a', oneOrMore('b'))).toEqual('ab+');
expect(compile('a', oneOrMore('bc'))).toEqual('a(bc)+');
expect(compile('a', oneOrMore('bc'))).toEqual('a(bc)+');
expect(compile(optionally('a'), 'b')).toEqual('a?b');
});
test('regex constructor', () => {
expect(regex('a').test('a')).toBeTruthy();
expect(regex('a').test('b')).toBeFalsy();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment