UNPKG

regops

Version:

A small javascript library for performing operations on regular expressions

151 lines (131 loc) 4.49 kB
/** Convert a list of convert regexs to their source strings. */ function sourcify(list:(RegExp | String | null)[]):string[] { return (list .filter(item => item) as (RegExp|string)[]) // remove null items .map(item => item instanceof RegExp ? item.source : item) } /** Put non-capturing brackets around a regex source string. */ function bracket(str:string) { return "(?:" + str + ")" } /** If necessary, put non-capturing brackets around a regex source string. */ function autoBracket(str:string) { if(/^[\w, ]*$/.test(str)) return str else return bracket(str) } /** Concatenate a list a of regular expressions. */ function concat(...operands:(RegExp | string | null)[]) { return new RegExp( sourcify(operands) .map(autoBracket) .join("") ) } /** Concatenate a list of regular expressions with a single-space (' ') delimiter.*/ function concatSpaced(...operands:(RegExp|string|null)[]) { return new RegExp( sourcify(operands) .map(autoBracket) .join(" ") ) } /** Combine regular expressions with OR (|) operator. */ function or(...operands:(RegExp|string|null)[]) { return new RegExp( sourcify(operands) .map(autoBracket) .join("|") ) } /** Apply OPTIONAL (?) operator to a regular expressions. */ function optional(operand:RegExp|string) { operand = new RegExp(operand).source operand = bracket(operand) return operand + "?" } /** Apply Kleene closure (*) operator to a regular expression. */ function kleene(operand:RegExp|string) { operand = new RegExp(operand).source operand = bracket(operand) return operand + "*" } /** Apply Kleene closure (*) operator to a regular expression, delimiting repetitions with a single-space (' ') */ function kleeneSpaced(operand:RegExp|string) { return kleeneJoin(operand, ' ') } /** Apply Kleene repetitions of a regular expression with some specified delimiter. */ function kleeneJoin(operand:RegExp|string, delimiter:string) { operand = new RegExp(operand).source delimiter = new RegExp(delimiter).source return concat(operand, kleene(concat(delimiter, operand))) } /** Create a "polite list" (form: X, X, X and X) using Kleene closure to allow any number of items. */ function kleenePoliteList(...operands:(RegExp|string)[]) { let operand = or(...operands) return concat( optional(concat(kleeneJoin(operand,', '), ',? and ')), operand ) } /** Concatenate a list of regular expressions with optional (?) modifiers. */ function optionalConcatSpaced( stem:RegExp|string, ...optionalAppendages:(RegExp|string|null)[] ) { stem = autoBracket(new RegExp(stem).source) optionalAppendages = sourcify(optionalAppendages) .map(a => autoBracket(a)) .map(a => optional(" " + a)) return concat(stem, ...optionalAppendages) } /** Concatenate an item with itself any number of times (using kleene closure *) using a single-space (' ') as a delimiter. */ function kleeneConcatSpaced( stem:RegExp|string, ...optionalAppendages:(RegExp|string|null)[] ) { stem = autoBracket(new RegExp(stem).source) optionalAppendages = sourcify(optionalAppendages) let toConcat = kleene(concat(' ', or(...optionalAppendages).source)) return concat(stem, toConcat) } /** Add ^ and $ markers either side of a regular expression so that it must match an entire string. */ function whole(operand:RegExp|string) { operand = autoBracket(new RegExp(operand).source) return new RegExp('^'+operand+'$') } /** Add a ^ marker at the beginning of a regular expression, so that it must match the beginning of a string. */ function initial(operand:RegExp|string) { operand = autoBracket(new RegExp(operand).source) return new RegExp('^'+operand) } /** Add a $ marker at the end of a regular expression, so that it matches the end of a string. */ function terminal(operand:RegExp|string) { operand = autoBracket(new RegExp(operand).source) return new RegExp(operand+'$') } /** Surround a regular expression with capturing parentheses, optionally specifying a group name. */ function capture(operand:RegExp|string, groupName:string) { if(operand instanceof RegExp) operand = operand.source let name = groupName ? '?<'+groupName+'>' : '' return new RegExp('(' + name + operand + ')') } export { concat, concatSpaced, or, optional, kleene, kleeneJoin, kleeneSpaced, kleenePoliteList, kleeneConcatSpaced, optionalConcatSpaced, autoBracket, whole, initial, terminal, capture, }