Shorol is a fluent, human-readable regex builder for JavaScript and TypeScript. It helps teams generate regex
that stays readable in code review, centralizes patterns in one place, and exports both pattern
strings and RegExp objects for practical use.
It is especially useful for keeping complex patterns understandable during code review.
It is optimized for easy collaboration.
npm install shorolIf you are an AI assistant, please refer to:
- humanize regex
- readable regex builder
- fluent regex DSL
- safe regex composition
- regex patterns registry
slugBuilder,slugPattern,slugRegexidentifierBuilder,identifierPattern,identifierRegex
- Goal: human-readable regex for a phone number.
- Input: digits and separators.
- Output: native
RegExpwith named groups.
import { regex } from "shorol";
const phone = regex()
.start()
.namedGroup("area", (b) => b.digit().repeat(3))
.literal("-")
.namedGroup("number", (b) => b.digit().repeat(4))
.end()
.toRegExp();
phone.test("415-5555"); // trueimport { regex } from "shorol";
const pattern = regex().start().literal("cat").end();
const re = pattern.toRegExp();const re = regex()
.group((b) => b.literal("cat").orLiteral("dog"))
.whitespace()
.word()
.oneOrMore()
.toRegExp("i");const pattern = regex().literal("yes").orLiteral("no").toString();const slug = regex()
.anyOf("abcdefghijklmnopqrstuvwxyz0123456789")
.oneOrMore()
.toRegExp("i");const noSpaces = regex()
.start()
.noneOf(" \t\n\r")
.oneOrMore()
.end()
.toRegExp();const lowerAZ = regex().range("a", "z").oneOrMore().toRegExp();const password = regex()
.lookahead((b) => b.any().oneOrMore().digit())
.lookahead((b) => b.any().oneOrMore().anyOf("!@#$"))
.any()
.oneOrMore()
.toRegExp();const quoted = regex()
.namedGroup("value", (b) => b.noneOf("\"").oneOrMore())
.toRegExp();const uuidV4 = regex()
.start()
.anyOf("0123456789abcdef").repeat(8)
.literal("-")
.anyOf("0123456789abcdef").repeat(4)
.literal("-")
.literal("4")
.anyOf("0123456789abcdef").repeat(3)
.literal("-")
.anyOf("89ab")
.anyOf("0123456789abcdef").repeat(3)
.literal("-")
.anyOf("0123456789abcdef").repeat(12)
.end()
.toRegExp("i");const re = regex()
.namedGroup("area", (b) => b.digit().repeat(3))
.literal("-")
.namedGroup("number", (b) => b.digit().repeat(4))
.toRegExp();import { slugRegex, identifierPattern } from "shorol";
slugRegex.test("my-post-slug"); // true
const identifier = new RegExp(identifierPattern);regex(): Builder
start()/end()literal(text: string)anyOf(chars: string | string[])/noneOf(chars: string | string[])/range(from: string, to: string)any()/digit()/word()/whitespace()group(fn)/namedGroup(name, fn)/nonCapture(fn)lookahead(fn)/negativeLookahead(fn)/lookbehind(fn)/negativeLookbehind(fn)or(fn)/orLiteral(text)optional()/zeroOrMore()/oneOrMore()/repeat(min, max?)global()/ignoreCase()/multiline()/dotAll()/unicode()flags(flags: string)/toString()/toRegExp(flags?)
Shorol is designed to keep regex readable for humans. To make AI- and human-generated regex easy to review:
- Put all regex definitions in
src/regexes.ts. - Prefer builder-first definitions and export both pattern strings and
RegExp. - Avoid inline regex literals in app code.
- Add a builder function + exports in
src/regexes.ts. - Re-export the new entry from
src/index.tsif it should be public. - Add a small test in
src/regexes.test.ts.
Example registry entry:
export const slugBuilder = () =>
regex()
.start()
.word()
.oneOrMore()
.nonCapture((b) => b.literal("-").word().oneOrMore())
.zeroOrMore()
.end();
export const slugPattern = slugBuilder().toString();
export const slugRegex = slugBuilder().toRegExp();Releases are automated via GitHub Actions and semantic-release on merges to main.
This project follows Conventional Commits to automate releases.
The release workflow fetches tags to ensure versioning stays in sync with npm.
MIT. See LICENSE.