Everything you need to write regex like a normal person. No PhD required.
npm install zeroreg
# or
pnpm add zeroreg
yarn add zeroreg
bun add zeroregimport { digit } from 'zeroreg'
// Match a phone number: 123-456-7890
const phone = digit(3).then('-').then(digit(3)).then('-').then(digit(4))
phone.test('123-456-7890') // true
phone.toRegex() // /\d{3}-\d{3}-\d{4}/import { email, url, phone } from 'zeroreg/patterns'
email.test('hello@world.com') // true
url.test('https://github.com') // true
phone.test('+1-234-567-8900') // trueMatch specific types of characters.
| Function | Description | Regex |
|---|---|---|
| digit(n?) | Match digits | \\d or \\d{n} |
| word() | Word char (a-z, 0-9, _) | \\w |
| letter() | Any letter a-z, A-Z | [a-zA-Z] |
| whitespace() | Whitespace | \\s |
| any() | Any character | . |
| literal(str) | Exact match (escaped) | str |
| charIn('abc') | Any char in set | [abc] |
| charNotIn('abc') | Any char NOT in set | [^abc] |
| range('a', 'z') | Character range | [a-z] |
import { digit, letter, charIn, literal } from 'zeroreg'
// Match exactly 3 digits
digit(3).test('123') // true
// Match a vowel
charIn('aeiou').test('e') // true
// Match a literal dot (escaped automatically)
literal('.').test('.') // trueControl how many times a pattern matches.
| Method | Description | Regex |
|---|---|---|
| .oneOrMore() | 1 or more | + |
| .zeroOrMore() | 0 or more | * |
| .optional() | 0 or 1 | ? |
| .times(n) | Exactly n times | {n} |
| .between(min, max) | Between min and max | {min,max} |
| .atLeast(n) | n or more times | {n,} |
import { digit, letter, optional } from 'zeroreg'
// One or more digits
digit().oneOrMore().test('123') // true
// Optional plus sign, then digits
optional('+').then(digit().oneOrMore()).test('+123') // true
optional('+').then(digit().oneOrMore()).test('123') // true
// Between 2 and 4 letters
letter().between(2, 4).test('abc') // trueCapture parts of your match or group patterns together.
| Function | Description | Regex |
|---|---|---|
| capture(pattern) | Capturing group | (...) |
| capture(pattern, 'name') | Named capture | (?<n>...) |
| group(pattern) | Non-capturing group | (?:...) |
| oneOf(a, b, c) | Match any of | (?:a|b|c) |
import { capture, digit, oneOf, group, literal } from 'zeroreg'
// Extract year, month, day
const datePattern = capture(digit(4), 'year')
.then('-')
.then(capture(digit(2), 'month'))
.then('-')
.then(capture(digit(2), 'day'))
const match = '2024-03-15'.match(datePattern.toRegex())
match.groups.year // '2024'
match.groups.month // '03'
match.groups.day // '15'
// Match "cat" or "dog" or "bird"
oneOf('cat', 'dog', 'bird').test('dog') // trueMatch positions in the string, not characters.
| Function | Description | Regex |
|---|---|---|
| startOfLine() | Start of string | ^ |
| endOfLine() | End of string | $ |
| wordBoundary() | Word boundary | \\b |
Convert your pattern to different formats and use it.
| Method | Returns | |
|---|---|---|
| .toRegex(flags?) | Native RegExp object | |
| .test(str) | boolean — does it match? | |
| .match(str) | First match or null/None | |
| .matchAll(str) | Array/list of all matches | |
| .replace(str, replacement) | String with replacements |
import { digit } from 'zeroreg'
const pattern = digit().oneOrMore()
// Test if string matches
pattern.test('abc123') // true
// Get all matches
pattern.matchAll('abc 123 def 456') // [['123'], ['456']]
// Replace all matches
pattern.replace('abc 123 def 456', 'X') // 'abc X def X'
// Get native RegExp with flags
pattern.toRegex('gi') // /\d+/giImport ready-to-use patterns for common use cases.
import { email, url, phone, date, uuid, ... } from 'zeroreg/patterns'emailuser@domain.com
urlhttps://example.com
phone+1-234-567-8900
date2024-03-15
time14:30:00
ipv4192.168.1.1
uuid550e8400-e29b-...
hexColor#ff6600
slugmy-post-title
hashtag#trending
mention@username
creditCard4111111111111111
usernameuser_123
strongPasswordMyP@ssw0rd
semver1.2.3-alpha
macAddress00:1A:2B:3C:4D:5E