regexus
Version:
Human Readable Regular Expressions
287 lines (286 loc) • 8.27 kB
JavaScript
/**
* @regexus v0.0.1
* Craft Regex with ease
*
* @license
* Copyright (c) undefined Alen Yohannan
* SPDX-License-Idntifier: ISC
* https://github.com/AlenVelocity/RegExus#readme
*/
class h {
constructor() {
this._flags = "", this._literal = [], this._groupsUsed = 0, this._min = -1, this._max = -1, this._of = "", this._ofAny = !1, this._ofGroup = -1, this._from = "", this._notFrom = "", this._like = null, this._either = null, this._reluctant = !1, this._capture = !1, this._captureName = null, this.clear();
}
clear() {
this._min = -1, this._max = -1, this._of = "", this._ofAny = !1, this._ofGroup = -1, this._from = "", this._notFrom = "", this._like = null, this._either = null, this._reluctant = !1, this._capture = !1;
}
flushState() {
if (this._of !== "" || this._ofAny || this._ofGroup > 0 || this._from !== "" || this._notFrom !== "" || this._like !== null) {
const t = this._capture ? this._captureName ? `?P<${this._captureName}>` : "" : "?:", i = this.getQuantityLiteral(), e = this.getCharacterLiteral(), r = this._reluctant ? "?" : "";
this._literal.push(`(${t}(?:${e})${i}${r})`), this.clear();
}
}
getQuantityLiteral() {
return this._min !== -1 ? this._max !== -1 ? `{${this._min},${this._max}}` : `{${this._min},}` : `{0,${this._max}}`;
}
getCharacterLiteral() {
switch (!0) {
case this._of !== "":
return this._of;
case this._ofAny:
return ".";
case this._ofGroup > 0:
return `\\${this._ofGroup}`;
case this._from !== "":
return `[${this._from}]`;
case this._notFrom !== "":
return `[^${this._notFrom}]`;
case this._like !== null:
return this._like;
default:
return "";
}
}
/**
* Returns the literal representation of the RegExp
* @returns {string}
*/
getLiteral() {
return this.flushState(), this._literal.join("");
}
combineGroupNumberingAndGetLiteralral(t) {
const i = this.incrementGroupNumbering(t.getLiteral(), this._groupsUsed);
return this._groupsUsed += t._groupsUsed, i;
}
incrementGroupNumbering(t, i) {
return i > 0 && (t = t.replace(/\\(\d+)/g, (e) => `\\${parseInt(e.substring(1)) + i}`)), t;
}
/**
* Returns the usable RegExp
* @returns {RegExp}
*/
getRegExp() {
return this.flushState(), new RegExp(this._literal.join(""), this._flags);
}
addFlag(t) {
return this._flags.indexOf(t) === -1 && (this._flags += t), this;
}
ignoreCase() {
return this.addFlag("i");
}
/**
* Makes the RegExp match across multiple lines
* @returns {RegExpBuilder}
*/
multiLine() {
return this.addFlag("m");
}
/**
* Enables global matching of the RegExp
* @returns {RegExpBuilder}
*/
globalMatch() {
return this.addFlag("g");
}
/**
* Starts the RegExp matching at the beginning of the input
* @returns {RegExpBuilder}
*/
startOfInput() {
return this._literal.push("(?:^)"), this;
}
/**
* Starts the RegExp matching at the beginning of the line
* @returns {RegExpBuilder}
*/
startOfLine() {
return this.multiLine(), this.startOfInput();
}
/**
* Ends the RegExp matching at the end of the input
* @returns {RegExpBuilder}
*/
endOfInput() {
return this.flushState(), this._literal.push("(?:$)"), this;
}
/**
* Ends the RegExp matching at the end of the line
* @returns {RegExpBuilder}
*/
endOfLine() {
return this.multiLine(), this.endOfInput();
}
/**
* Matches the input string against the RegExp
* @param {string} input
* @returns {boolean}
*/
eitherFind(t) {
return typeof t == "string" ? this.setEither(this.getNew().exactly(1).of(t)) : this.setEither(t);
}
setEither(t) {
return this.flushState(), this._either = this.combineGroupNumberingAndGetLiteralral(t), this;
}
orFind(t) {
return typeof t == "string" ? this.setOr(this.getNew().exactly(1).of(t)) : this.setOr(t);
}
anyOf(t) {
if (t.length < 1)
return this;
const i = t.shift();
return this.eitherFind(i), t.forEach((e) => {
this.orFind(e);
}), this;
}
setOr(t) {
const i = this._either, e = this.combineGroupNumberingAndGetLiteralral(t);
if (i === null) {
let r = this._literal[this._literal.length - 1];
r = r.substring(0, r.length - 1), this._literal[this._literal.length - 1] = r, this._literal.push(`|(?:${e}))`);
} else
this._literal.push(`(?:(?:${i})|(?:${e}))`);
return this.clear(), this;
}
neither(t) {
return typeof t == "string" ? this.notAhead(this.getNew().exactly(1).of(t)) : this.notAhead(t);
}
nor(t) {
return this._min === 0 && this._ofAny && (this._min = -1, this._ofAny = !1), this.neither(t), this.min(0).ofAny();
}
exactly(t) {
return this.flushState(), this._min = t, this._max = t, this;
}
min(t) {
return this.flushState(), this._min = t, this;
}
max(t) {
return this.flushState(), this._max = t, this;
}
of(t) {
return this._of = this.sanitize(t), this;
}
ofAny() {
return this._ofAny = !0, this;
}
ofGroup(t) {
return this._ofGroup = t, this;
}
from(t) {
return this._from = this.sanitize(t.join("")), this;
}
notFrom(t) {
return this._notFrom = this.sanitize(t.join("")), this;
}
like(t) {
return this._like = this.combineGroupNumberingAndGetLiteralral(t), this;
}
reluctantly() {
return this._reluctant = !0, this;
}
ahead(t) {
return this.flushState(), this._literal.push(`(?=${this.combineGroupNumberingAndGetLiteralral(t)})`), this;
}
notAhead(t) {
return this.flushState(), this._literal.push(`(?!${this.combineGroupNumberingAndGetLiteralral(t)})`), this;
}
asGroup(t = null) {
return this._capture = !0, this._captureName = t, this._groupsUsed++, this;
}
then(t) {
return this.exactly(1).of(t);
}
find(t) {
return this.then(t);
}
some(t) {
return this.min(1).from(t);
}
maybeSome(t) {
return this.min(0).from(t);
}
maybe(t) {
return this.max(1).of(t);
}
anything() {
return this.min(0).ofAny();
}
anythingBut(t) {
return t.length === 1 ? this.min(1).notFrom([t]) : (this.notAhead(this.getNew().exactly(1).of(t)), this.min(0).ofAny());
}
something() {
return this.min(1).ofAny();
}
any() {
return this.exactly(1).ofAny();
}
lineBreak() {
return this.flushState(), this._literal.push("(?:\\r\\n|\\r|\\n)"), this;
}
lineBreaks() {
return this.like(this.getNew().lineBreak());
}
whitespace() {
return this._min === -1 && this._max === -1 ? (this.flushState(), this._literal.push("(?:\\s)"), this) : (this._like = "\\s", this);
}
notWhitespace() {
return this._min === -1 && this._max === -1 ? (this.flushState(), this._literal.push("(?:\\S)"), this) : (this._like = "\\S", this);
}
tab() {
return this.flushState(), this._literal.push("(?:\\t)"), this;
}
tabs() {
return this.like(this.getNew().tab());
}
digit() {
return this.flushState(), this._literal.push("(?:\\d)"), this;
}
notDigit() {
return this.flushState(), this._literal.push("(?:\\D)"), this;
}
digits() {
return this.like(this.getNew().digit());
}
notDigits() {
return this.like(this.getNew().notDigit());
}
letter() {
return this.exactly(1), this._from = "A-Za-z", this;
}
notLetter() {
return this.exactly(1), this._notFrom = "A-Za-z", this;
}
letters() {
return this._from = "A-Za-z", this;
}
notLetters() {
return this._notFrom = "A-Za-z", this;
}
lowerCaseLetter() {
return this.exactly(1), this._from = "a-z", this;
}
lowerCaseLetters() {
return this._from = "a-z", this;
}
upperCaseLetter() {
return this.exactly(1), this._from = "A-Z", this;
}
upperCaseLetters() {
return this._from = "A-Z", this;
}
append(t) {
return this.exactly(1), this._like = this.combineGroupNumberingAndGetLiteralral(t), this;
}
optional(t) {
return this.max(1), this._like = this.combineGroupNumberingAndGetLiteralral(t), this;
}
sanitize(t) {
return t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
getNew() {
const t = this.constructor;
return new t();
}
}
export {
h as RegExpBuilder
};