ts-regex-builder
Version:
Maintainable regular expressions for TypeScript and JavaScript.
54 lines • 1.57 kB
JavaScript
import { ensureElements, ensureText } from "./utils.mjs";
export function encode(sequence) {
const elements = ensureElements(sequence);
const encoded = elements.map(n => encodeElement(n));
if (encoded.length === 1) {
return encoded[0];
}
return {
precedence: 'sequence',
pattern: encoded.map(n => n.precedence === 'disjunction' ? encodeAtomic(n) : n.pattern).join('')
};
}
export function encodeAtomic(sequence) {
const encoded = encode(sequence);
return encoded.precedence === 'atom' ? encoded.pattern : `(?:${encoded.pattern})`;
}
function encodeElement(element) {
if (typeof element === 'string') {
return encodeText(element);
}
if (element instanceof RegExp) {
return encodeRegExp(element);
}
if (typeof element === 'object') {
if ('pattern' in element) {
return element;
}
if ('encode' in element) {
return element.encode();
}
}
throw new Error(`Unsupported element. Received: ${JSON.stringify(element, null, 2)}`);
}
function encodeText(text) {
ensureText(text);
return {
precedence: text.length === 1 ? 'atom' : 'sequence',
pattern: escapeText(text)
};
}
function encodeRegExp(regexp) {
const pattern = regexp.source;
return {
precedence: isAtomicPattern(pattern) ? 'atom' : 'disjunction',
pattern
};
}
function isAtomicPattern(pattern) {
return pattern.length === 1 || /^\[[^[\]]*\]$/.test(pattern) || /^\([^()]*\)$/.test(pattern);
}
function escapeText(text) {
return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
//# sourceMappingURL=encoder.mjs.map