UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

73 lines (72 loc) 3.38 kB
import { RequiredError } from "../error/RequiredError.js"; import { ValueError } from "../error/ValueError.js"; import { getArray } from "./array.js"; /** Regular expression that always matches everything. */ export const ALWAYS_REGEXP = /^.*$/; /** Regular expression that never matches anything. */ export const NEVER_REGEXP = /^(?=a)a/; /** Is an unknown value a `RegExp` instance? */ export function isRegExp(value) { return value instanceof RegExp; } /** Assert that an unknown value is a `RegExp` instance. */ export function assertRegExp(value) { if (!(value instanceof RegExp)) throw new RequiredError("Must be regular expression", { received: value, caller: assertRegExp }); } export function getRegExp(pattern, flags) { return typeof pattern === "string" ? new RegExp(pattern, flags) : pattern; } /** Convert a regular expression to its string source. */ export function getRegExpSource(regexp) { return typeof regexp === "string" ? regexp : regexp.source; } /** Escape special characters in a string regular expression. */ export function escapeRegExp(pattern) { return pattern.replace(REPLACE_ESCAPED, "\\$&"); } const REPLACE_ESCAPED = /[-[\]/{}()*+?.\\^$|]/g; /** Create regular expression that matches any of a list of other expressions. */ export function createRegExpAny(patterns, flags) { const arr = getArray(patterns).filter(Boolean); // If there are no patterns to match against then _no_ string can ever match against any of nothing. if (!arr.length) return NEVER_REGEXP; // Create RegExp using multiple joined matches like `(?:AAA)|(?:BBB)` return new RegExp(`(?:${getArray(patterns).map(getRegExpSource).join(")|(?:")})`, flags); } /** Create regular expression that matches all of a list of other expressions. */ export function createRegExpAll(patterns, flags) { const arr = getArray(patterns).filter(Boolean); // If there are no patterns to match against then _every_ string will match against the entire list of nothing. if (!arr.length) return ALWAYS_REGEXP; // Create RegExp using multiple lookaheads like `^(?=.*?(?:AAA))(?=.*?(?:BBB))` return new RegExp(`^(?=.*?(?:${getArray(patterns).map(getRegExpSource).join("))(?=.*?(?:")}))`, flags); } /** Match function for finding strings that match against regular expressions (use with `filter()` to positively filter iterable sets of items). */ export function isMatch(str, regexp) { return regexp.test(str); } /** Match function for finding strings that match against regular expressions (use with `filter()` to negatively filter iterable sets of items). */ export function notMatch(str, regexp) { return !regexp.test(str); } export function getMatch(str, regexp) { return regexp.exec(str) || undefined; } export function requireMatch(str, regexp) { const match = getMatch(str, regexp); if (!match) throw new ValueError("Must match regular expression", { received: str, expected: regexp, caller: requireMatch }); return match; } export function getMatchGroups(str, regexp) { return regexp.exec(str)?.groups || undefined; } export function requireMatchGroups(str, regexp) { const groups = getMatchGroups(str, regexp); if (!groups) throw new ValueError("Must match regular expression", { received: str, expected: regexp, caller: requireMatchGroups }); return groups; }