UNPKG

@discretetom/r-compose

Version:

Compose RegExp in JavaScript in a readable and maintainable way.

174 lines 6.16 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.compose = exports.composables = void 0; function intoString(content) { return content instanceof RegExp ? content.source : content; } /** * All the composable functions. */ exports.composables = Object.freeze({ /** * Escape regex special characters. * @example * escape("(a*b)") === "\\(a\\*b\\)" */ escape(content) { // use the `g` flag to replace all occurrences return content.replace(/[/\-\\^$*+?.()|[\]{}]/g, "\\$&"); }, /** * Concatenate strings. * Empty strings are ignored. * If a parameter is a `RegExp`, its source is used. * @example * concat("a", "b") === "ab" * concat("a", '', "b") === "ab" * concat('a', /\./, 'b') === "a\\.b" */ concat(...contents) { return contents .map(intoString) .filter((c) => c.length) .join(""); }, /** * Match a list of candidates. * Empty strings are ignored. * If a parameter is a `RegExp`, its source is used. * The result is wrapped in a non-capturing group. * @example * select("a", "b") === "(?:a|b)" * select("a", '', "b") === "(?:a|b)" * select('a', /\./, 'b') === "(?:a|\\.|b)" */ select(...contents) { return `(?:${contents .map(intoString) .filter((c) => c.length) .join("|")})`; }, /** * Wrap the content by a non-capturing group. * If the content is a `RegExp`, its source is used. * @example * group("a") === "(?:a)" * group(/\./) === "(?:\\.)" * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions/Groups_and_backreferences */ group(content) { return `(?:${intoString(content)})`; }, /** * Wrap the content by a capturing group. * If the content is a `RegExp`, its source is used. * @example * capture("a") === "(a)" * capture(/\./) === "(\\.)" * capture("a", { name: "n" }) === "(?<n>a)" * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions/Groups_and_backreferences */ capture(content, options) { return (options === null || options === void 0 ? void 0 : options.name) === undefined ? `(${intoString(content)})` : `(?<${options.name}>${intoString(content)})`; }, /** * Match zero or more times (`*`). * If the content is a `RegExp`, its source is used. * @example * any("a") === "(?:a)*" * any(/\./) === "(?:\\.)*" * any("a", { greedy: false }) === "(?:a)*?" * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions/Quantifiers */ any(content, options) { var _a; return ((_a = options === null || options === void 0 ? void 0 : options.greedy) !== null && _a !== void 0 ? _a : true) ? `(?:${intoString(content)})*` : `(?:${intoString(content)})*?`; }, /** * Match one or more times (`+`). * If the content is a `RegExp`, its source is used. * @example * some("a") === "(?:a)+" * some(/\./) === "(?:\\.)+" * some("a", { greedy: false }) === "(?:a)+?" * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions/Quantifiers */ some(content, options) { var _a; return ((_a = options === null || options === void 0 ? void 0 : options.greedy) !== null && _a !== void 0 ? _a : true) ? `(?:${intoString(content)})+` : `(?:${intoString(content)})+?`; }, /** * Match zero or one time (`?`). * If the content is a `RegExp`, its source is used. * @example * optional("a") === "(?:a)?" * optional(/\./) === "(?:\\.)?" * optional("a", { greedy: false }) === "(?:a)??" * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions/Quantifiers */ optional(content, options) { var _a; return ((_a = options === null || options === void 0 ? void 0 : options.greedy) !== null && _a !== void 0 ? _a : true) ? `(?:${intoString(content)})?` : `(?:${intoString(content)})??`; }, /** * If the content is a `RegExp`, its source is used. * @example * lookahead("a") === "(?=a)" * lookahead(/\./) === "(?=\\.)" * lookahead("a", { negative: true }) === "(?!a)" * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions/Assertions */ lookahead(content, options) { var _a; return ((_a = options === null || options === void 0 ? void 0 : options.negative) !== null && _a !== void 0 ? _a : false) ? `(?!${intoString(content)})` : `(?=${intoString(content)})`; }, /** * If the content is a `RegExp`, its source is used. * @example * lookbehind("a") === "(?<=a)" * lookbehind(/\./) === "(?<=\\.)" * lookbehind("a", { negative: true }) === "(?<!a)" * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions/Assertions */ lookbehind(content, options) { var _a; return ((_a = options === null || options === void 0 ? void 0 : options.negative) !== null && _a !== void 0 ? _a : false) ? `(?<!${intoString(content)})` : `(?<=${intoString(content)})`; }, /** * Match any character except the ones in the content. * If the content is a `RegExp`, its source is used. * @example * not("a") === "[^a]" * not(/\./) === "[^\\.]" */ not(content) { return `[^${intoString(content)}]`; }, /** * @alias String.raw * @example * raw`\n` === "\\n" */ raw: String.raw, }); /** * @example * compose(({ concat, group }) => concat(group("a"), group("b")), 'g') === /(?:a)(?:b)/g */ function compose(cb, flags) { return new RegExp(cb(exports.composables), flags); } exports.compose = compose; //# sourceMappingURL=index.js.map