Skip to content

Latest commit

 

History

610 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🧠 Regex For Humans

Regex For Humans: little rules, big aha moments

Write it. Understand it. Test it.

A few clear English rules become a JavaScript regex you can actually follow.

🔒 Runs locally   🧩 No runtime dependencies   ⚡ One compiler, three ways to use it

English · 简体中文 · Español · Français · Português do Brasil · 日本語 · Deutsch · हिन्दी · العربية · اردو


🪄 Less squinting. More matching.

Regex punctuation gets easier to read when you can see where it came from.

✍️ Your rules✨ Your JavaScript regex
start "#"
6 hex digits
end
/^#[0-9A-Fa-f]{6}$/u

✅ #12aBcF · #000000
❌ #123 · #G00000

A small, fixed vocabulary, with an exact meaning for every instruction. The library, CLI, and workshop use the same deterministic compiler. Unknown phrases get a line, column, and helpful diagnostic.

🌱 Development preview (0.1.0-dev.12): the library and CLI need Node.js 22+. The hosted workshop works without installation. Human usability and screen reader reviews are still pending.

Complete a rule: use Complete a rule or Ctrl + Space to finish built-in character classes, including after a count (for example, between 2 and 5 di), or references to earlier closed captures (same as ca). References are offered by number and by name; a preview displays the complete selected rule. Every suggestion must compile with the entire document. Quoted text, comments and selected text are preserved. See completion scope and controls.

Source follow-up after dev.12: completion also offers eight balanced group/assertion templates. The preview shows the proposed document, including reference updates when a new capture changes numbering; the cursor lands in the first body rule. This addition awaits the next verified workshop release.

Start here Continue with
Install · Playground Recipes · Complex examples
Captures · Cheat sheet CLI · JavaScript / TypeScript
Capabilities · Flags Local development · FAQ

🧰 What you can build today

Markdown reports: export a Markdown report with the build label, rules, exact JavaScript regex, options, intended tests and reimportable JSON. Exporting does not run or certify the tests.

Capability npm 0.1.0-dev.12 API / hosted workshop
Readable rules → native JavaScript regex ✅
Supported regex → editable rules ✅
Fragment explanations and source navigation ✅
CLI, ESM API and TypeScript declarations ✅
Numbered/named captures and nested blocks ✅
Whole-block repetition and backward references ✅
Ordered alternatives with either { … } ✅
Lazy repetition with lazy ✅
Lookaround ✅
Word boundaries ✅
Unicode character properties ✅
Composable character classes ✅
Native Unicode string and nested set operations ✅
All eight JavaScript flags ✅
Group editing and capture highlighting ✅
Interactive structure and SVG export ✅
Structural risk review ✅
Engine-aware code exports ✅
Free-form English —

The workshop now offers Edit groups and references: rename captures, change named/numbered/noncapturing forms and jump to their references. Numeric references keep their original targets when numbering changes; removing a referenced capture is rejected without changing the rules. Highlight selects a capture's native input range, including empty captures and captures outside the consumed match. The shared editGroup API returns validated rules. See group editing.

Open Explore the pattern for an AST-driven railroad diagram. See nested groups, ordered alternatives, repetition loops and zero-width checks; hover or select to connect rules, regex fragments and explanations. Actual size keeps text readable; Fit overview shows the whole map. Export SVG saves a standalone file, also available through toSVG(rules, { flags }). This shows structure, not runtime backtracking. Read structural diagrams.

With this preview, lazy digits generates \d+?: try one digit first, then expand if following rules need more. lazy any text generates .*?. Available in npm 0.1.0-dev.12; see greedy and lazy repetition.

The compiler also supports followed by { … }, not followed by { … }, preceded by { … }, not preceded by { … }. They test surrounding text without consuming it. Captures keep native values and positions, which can lie outside the consumed match; lookbehind requires runtime support. Available in npm 0.1.0-dev.12; see lookaround assertions.

The compiler supports word boundary (\b) and not word boundary (\B). These zero-width checks use native JavaScript word status: ASCII letters, digits and underscore, plus case-folding equivalents with i. They do not segment natural-language words. Available in npm 0.1.0-dev.12; see word boundaries.

The compiler also accepts unicode property "L" and not unicode property "L" for native \p{L} and \P{L}. L means Letter; aliases are case-sensitive and classification uses the runtime’s Unicode data. Counts and lazy work as usual. With i, the native u complement can include case-folded letters. Available in npm 0.1.0-dev.12; see Unicode properties.

The compiler supports range "α" to "ω" and character class: digit, "_". Combine one-code-point literals, ranges, singular shorthands and Unicode properties in one class; not character class: negates the whole union. Counts and lazy apply to the class. Property complements keep their native u/i behavior. Available in npm 0.1.0-dev.12; see character classes.

The 0.1.0-dev.12 preview includes groups, captures, backward references and ordered alternatives in the library and CLI. The browser workshop adds capture inspection and multiple search matches. See compatibility and distribution records for the precise evidence.

🌍 Export to your language

Open Export to a programming language in the local workshop, call exportRegex(rules, { target: "python" }), or run node bin/regex-for-humans.js --target python --json rules.txt. Nine formats cover JavaScript, TypeScript, Python, Rust, Go, Java, C#, PHP and Ruby. JavaScript/TypeScript retain the existing native pattern; other targets translate supported AST semantics before quoting source code.

Seven native engines have passed generated-code comparisons; PHP is verified on PHP 8.5.11 / PCRE2 10.44. See the tested editions and corpus limits in the compatibility guide. Keep the returned requirements and capture mapping: foreign captures use gN names, and inactive names can be absent. Foreign input must be well-formed Unicode. Unsupported flags (d/g/i/y), Unicode properties and incompatible assertions or capture/repetition behavior produce positioned diagnostics. Download code or the complete export JSON; browser examples still run in JavaScript. Read the profiles and limits.

📦 Install the preview

npm install regex-for-humans@preview

Use the CLI without a global install:

printf 'start "ABC"\n3 digits\nend\n' | npx --yes --package=regex-for-humans@preview regex-for-humans

This prints /^ABC\d{3}$/u. To pin the exact preview, use regex-for-humans@0.1.0-dev.12. There are no runtime dependencies or standalone OS executables.

🎮 Play with a pattern

Choose Interface language for English, Simplified Chinese, Spanish or French. Labels, recipes, match feedback and navigation controls update without changing your rules, examples, selections, open panels or generated code. The choice is remembered locally when storage is available. Rules still use controlled English; compiler explanations, diagram labels and exported technical requirements stay in English. See workshop localization.

Use Theme to follow your system appearance or choose a light or dark workshop. The preference is saved locally when storage is available; changing appearance retains your rules, examples, selections and open panels. See theme preference.

the native rule editor colors keywords, quoted strings, captures, quantifiers, assertions, alternatives and comments. It underlines the compiler's diagnosed token while retaining normal typing, selection, copy and scrolling; forced colors and inputs beyond the budgets use plain native text. Whole-line # comments keep their source locations and consume the usual budgets. See comments and editor highlighting.

Build a rule inserts editable capture, optional-section, alternative, repetition, character-class and assertion templates before the current line or selection, inside outer anchors. Adding a capture keeps existing numbered references aimed at the same groups. Invalid or oversized insertions retain the original rules and selection; flags and examples stay in place. See rule construction.

Exact expectations checks complete UTF-16 spans, ordered capture values (null for absence, "" for an empty capture) and JavaScript replacement results using the original flags. Test fixtures imports/exports versioned JSON and manually saves/restores examples locally. Invalid drafts/files retain current work; imported CR/CRLF stays exact until the example field is edited. See the fixture format, examples and limits.

Share a workshop snapshot with Copy share link: preserve rules, flags, match mode, examples and exact expectations in one URL. A fresh page restores it before recipes load; Load shared link explicitly replaces work already in progress. Clipboard refusal leaves a manual-copy field. Links are limited to 32 KiB; larger suites use JSON export. Anyone with the link can read its contents: it is not encrypted. See sharing and its limits.

Draft recovery. Enable Keep a draft in this browser to recover rules, flags, examples, pasted regex and even unfinished expectation JSON after reload. It is off by default, keeps manual saved tests separate and removes the draft when disabled. See recovery and storage limits.

Preview group edits. Choose Preview group edit to compare the current and proposed rules and regex, including renamed or renumbered references. Preview keeps your tests and saved draft; changing source, flags or group fields clears it. Apply the edit to test its result. See before/after comparisons and their limits.

Understand a failed example from native match ranges or provable minimum lengths, missing literals and literal text at the wrong absolute input edge. Prefix/suffix proofs apply to case-sensitive input anchors; line anchors and uncertain cases keep conservative explanations. The workshop admits when the precise failing step is unavailable. This is not a backtracking trace. See failure explanations.

Go to the exact diagnostic for a malformed quoted escape, invalid class/list item, range endpoint or Unicode property alias. Highlighting keeps the original escaped spelling and complete Unicode pairs; errors without a known range retain point navigation. The library and CLI expose optional exclusive UTF-16 endColumn metadata. See diagnostic ranges.

  1. Pick a recipe or write one instruction per line.
  2. Follow the fragments to see what every rule means.
  3. Try your examples and mark what should match.
  4. Copy the regex when the results make sense.

Partial matches show a short escaped input preview with the match highlighted; an empty match gets a caret marker.

Open a match in the current workshop to inspect capture values and native spans. Absent groups and empty captures stay distinct; repeated groups show their final value. Search anywhere lists up to 100 nonoverlapping matches and advances empty matches by a Unicode code point. Positions count UTF-16 units, with the end excluded. Engines without capture indices show values without inferred positions.

Your rules and examples stay in the browser. No account, AI interpretation, or application backend.

🔄 Already have a regex?

Paste a supported JavaScript regex literal into Already have a regex? in the workshop and turn it into editable rules. Press Ctrl/Cmd + Enter in the regex field or choose Translate to rules. For example, /^[A-Z]{2}-\d{4}$/u becomes:

start
2 uppercase letter
"-"
4 digit
end

The workshop expects a slash-delimited literal with u or v; write line breaks as escapes such as \n. The reverse translator preserves supported flags. The 0.1.0-dev.12 preview imports numbered/named captures, nested groups, ordered alternatives, backward references, lookaround and lazy quantifiers, preserving capture values and numbering. Forward/open references remain unsupported; see the language guide for its limits.

Reverse translation also handles JavaScript's empty negative class [^], which includes line breaks. When ordinary . atoms appear beside it, their output rules explicitly exclude line terminators so matching stays the same.

Letter and hex ranges can appear in equivalent orders: [a-zA-Z] becomes letter, and all six orders of 0-9, A-F and a-f become hex digit. Generated regexes use a canonical range order with the same matching behavior.

Path-component exclusions become readable rules too: /^[^/\\\0\n\r\u2028\u2029]{1,32}$/u becomes start, between 1 and 32 path segment character, end on separate lines. Reordering, duplicate exclusions and equivalent escape spellings keep the same translation.

Control-letter escapes also translate: /^\cJ{2}$/u becomes start, 2 "\n", end on separate lines. Control characters stay visible as escapes in the rules and generated regex.

Separator lists such as [._-] and [-._] translate too: a hyphen at either end stays literal. The generated class escapes it as \-.

Alternatives become editable either { … } blocks: each entry is one ordered choice. Use group { … } for a sequence or an empty choice. Literal pipes such as \| or [|] remain matching data.

Unsupported contents inside assertions remain errors: /^😀(?=ab[])a/u points to the empty class’s [ at column 9. Unsupported forward/open references point to their escape. Use Go to regex error to select that character in your pasted pattern and bring it into view. Failed translation preserves your current rules and options.

Empty non-capturing groups translate too: /(?:)/u becomes 0 any character. Search mode finds an empty match at position 0, including in nonempty input; Entire string mode accepts only blank input for this pattern.

Real desktop workshop showing editable rules, generated regex, explanations, and passing example checks

📱 See the mobile workshop

Mobile view of the Regex For Humans workshop

Real screenshot details and checksums.

🍱 Recipes to start with

Try this Example What it checks
🏷️ Prefixed ID ABC123 ABC + exactly three digits
🧾 Invoice ID shape INV-1234 INV- + two to six ASCII digits
👤 Username shape Alice_7 ASCII letter first, then word characters; 3–16 total
🎨 Hex color #12aBcF Six hexadecimal digits after #, either letter case
🔌 MAC address shape 00:1A:2B:3C:4D:5E Six colon-separated pairs of ASCII hexadecimal digits
🪪 UUID shape f81d4fae-7dec-11d0-a765-00a0c91e6bf6 Five ASCII hex groups of 8–4–4–4–12 characters, either letter case
🔡 Product-code shape AB-rgb-0420 Two uppercase, three lowercase ASCII letters, and four digits
📅 Date shape 2026-09-30 The YYYY-MM-DD shape
⏰ Time shape 09:30 The HH:MM shape with ASCII digits
📞 Phone-number shape +33123456789 Optional +, then 7–15 ASCII digits
🌐 IPv4 address shape 192.0.2.42 Four groups of 1–3 ASCII digits; range checks are separate
📄 Text filename shape report.txt 1–64 Unicode code points before .txt, excluding separators, NUL and line breaks
🗃️ Complex artifact manifest Tab-separated path, checksum and size 19 rules, an optional directory, bounded Unicode path and nine preloaded test cases
🌐 Complex access log Address, timestamp, request and quoted fields 43 rules and eight preloaded cases; shape checks, without field extraction
🛰️ Complex telemetry event Timestamp, IDs, duration and optional values 38 rules and nine preloaded cases; independent optional lane value and retry suffix
📦 Version shape 1.2.3 Three numeric components
🚧 Excluded characters xyz Text without a chosen set of characters
📝 Line rule item 123 A line ending in at least three digits
Match a lowercase slug hello-world ASCII letters/digits with single hyphen separators
Find a file extension README.md Case-sensitive txt, md or json suffix
Match a UTC timestamp shape 2026-10-11T09:30:00Z Optional fractional seconds; calendar checks stay separate
Match a simple HTTPS URL shape https://example.com Small ASCII-host subset; not complete URL validation
Extract a simple header field Content-Type: application/json Named field and single-line value
Match a Markdown heading fragment # Hello One to six # characters and a heading
Validate SemVer 2.0 syntax 1.2.3-alpha.1+001 Core, prerelease and build syntax; no precedence comparison
Match a Git object hash shape aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 40 or 64 ASCII hex characters; existence checks stay separate
Match two repeated words hello hello Named backward reference to an ASCII word
Detect adjacent duplicate tokens item,item One comma-separated pair, 1–16 word characters each
Match Unicode letters and marks العربية / اردو Native L/M properties, including Arabic and Urdu
Extract named fields from a log fragment INFO code=200 Named level and code from a searched fragment
Search and replace a typo teh then teh → the then teh Exact spans, captures and non-global replacement expectations

The library contains 31 recipes across 24 categories and three difficulty levels. Search titles, limitations and rules in the four interface languages, then combine category and difficulty filters. See the library guide for scope and limits.

Failed examples also receive evidence-based explanations: native match ranges, a provable minimum length or an absent required literal. When the precise failing step is unknown, the workshop says so.

Choose beginner, intermediate or expert explanations. Beginner notes define regex terms; expert notes expose source ranges, capture identities, resolved references and flags. Changing the level preserves your work and runs no matching.

Shapes have limits: UUID shape follows the bare hex-and-dash layout in RFC 9562 section 4; version, variant and uniqueness require separate checks. Braces and a urn:uuid: prefix are excluded. text filename shape allows spaces, dots and punctuation; check filesystem rules and file existence separately. phone-number shape allows leading zeros and excludes spaces and punctuation; check country rules and number validity separately. invoice IDs allow leading zeros; verify invoice records separately. Username shape does not check availability or a service's account rules. Date shape accepts impossible dates such as 2026-02-31; validate calendar values separately. Time shape accepts 25:99; validate hour and minute ranges separately. Version shape allows leading zeros and rejects prerelease suffixes; it isn't full SemVer. Hex color accepts #RRGGBB, not shorthand, alpha, or every CSS color form. Product-code shape accepts only its stated ASCII letter case and counts; adding i ignores case, and the pattern does not verify catalog records.

🏗️ Bigger patterns, same readable rules

A three-digit ID is only the starting point. The full complex-examples guide walks through four substantial formats, with 35 accepted/rejected cases and the compiler's complete explanation for every rule:

Example What it combines
🌐 Access log 43 rules for address, timestamp, request, status and quoted fields
🛰️ Structured event 38 rules, trace/span IDs, bounded fields and independent optional values
📦 Artifact manifest Optional directory, variable version/path parts, checksum shape and TSV separators
🧾 Multiline order Unicode buyer, phone/amount shapes, optional approval value and complete optional priority line

📦 Example: an artifact manifest

Readable rules

start
"incoming/"
optional "nightly/"
between 1 and 32 path segment characters
"/v"
between 1 and 3 digits
"."
between 1 and 3 digits
"."
between 1 and 3 digits
"/linux-arm64/widget_"
8 digits
"_"
8 hex digits
".tar.gz\t"
64 hex digits
"\t"
between 1 and 12 digits
end

Exact generated JavaScript regex

/^incoming\/(?:nightly\/){0,1}[^\/\\\u{0}\u{a}\u{d}\u{2028}\u{2029}]{1,32}\/v\d{1,3}\.\d{1,3}\.\d{1,3}\/linux-arm64\/widget_\d{8}_[0-9A-Fa-f]{8}\.tar\.gz\u{9}[0-9A-Fa-f]{64}\u{9}\d{1,12}$/u

This synthetic schema accepts a path such as incoming/nightly/WidgetKit/v2.15.3/linux-arm64/widget_20261001_ab12cd34.tar.gz, followed by a tab, 64 hex digits, another tab and a 1–12 digit byte count. The whole nightly/ directory is optional. path segment characters replaces the long escaped exclusion list while keeping its exact matching behavior. Missing version parts, a non-hex token or spaces replacing the tabs are rejected. Check file existence, checksum contents and calendar/version semantics separately.

🧾 Second complete example: a multiline order

🧾 Example: a multiline order

Readable rules

start
"ORDER\nid=ORD-"
8 hex digits
"\nbuyer="
between 1 and 60 none of: "\u0000", "\n", "\r", "\u2028", "\u2029"
"\nphone="
optional "+"
between 7 and 15 digits
"\nitems="
between 1 and 4 digits
"\ntotal="
between 1 and 6 digits
"."
2 digits
" EUR\nreference="
16 hex digits
"\napproval="
optional one of: "A", "D"
"\n"
optional "priority=HIGH\n"
"END"
optional "\n"
end

Exact generated JavaScript regex

/^ORDER\u{a}id=ORD-[0-9A-Fa-f]{8}\u{a}buyer=[^\u{0}\u{a}\u{d}\u{2028}\u{2029}]{1,60}\u{a}phone=\+{0,1}\d{7,15}\u{a}items=\d{1,4}\u{a}total=\d{1,6}\.\d{2} EUR\u{a}reference=[0-9A-Fa-f]{16}\u{a}approval=[AD]{0,1}\u{a}(?:priority=HIGH\u{a}){0,1}END\u{a}{0,1}$/u

Zoë 😀 works as the buyer. The phone's +, approval's A/D value and whole priority=HIGH\n line are optional independently. A missing buyer, one decimal digit in the amount or an unsupported priority value fails. This schema uses explicit LF line endings; the library and CLI preserve that distinction, while browser textareas normalize pasted CRLF.

Captures in the preview: numbered and named capture blocks, nested group blocks, repetition of whole blocks and named/numbered references are available in npm 0.1.0-dev.12, including reverse translation of the supported subset. See the group syntax and complete date example. The flat worked examples above validate shapes without extracting fields.

🧲 Extract fields with named captures

A date can become three useful fields. This example works with npm 0.1.0-dev.12 and in the hosted workshop.

start
capture "year" {
  4 digits
}
"-"
capture "month" {
  2 digits
}
"-"
capture "day" {
  2 digits
}
end
import { compile, toRegExp } from './index.js';

const rules = `start
capture "year" {
  4 digits
}
"-"
capture "month" {
  2 digits
}
"-"
capture "day" {
  2 digits
}
end`;

const match = toRegExp(compile(rules)).exec('2026-10-10');
console.log(match?.groups); // { year: '2026', month: '10', day: '10' }

Use capture { for a numbered field and group { to group without extracting. Names are unique JavaScript identifiers; numbers follow opening order, including nested captures. Optional groups that do not participate return undefined; a participating empty capture returns "". A repeated capture retains its final value. These are native JavaScript semantics.

Need the same text twice? After the group's closing brace, write same as capture "word" or same as capture 1. The reference example matches cat cat and rejects cat dog. References before or inside their target receive a positioned diagnostic. The reverse translator preserves supported names, numbers and captured values.

This pattern validates YYYY-MM-DD, including impossible dates. Use calendar validation after extraction.

🧩 Your pocket cheat sheet

Put one instruction on each line. Quote literal text. Add anchors to check the whole string.

Say this Get this Meaning
start · end ^ · $ Input bounds
line start · line end ^ · $ + m Line bounds
digit · not digit \d · \D One digit / one non-digit
3 digits · digits \d{3} · \d+ Exactly three / one or more
lowercase letters · uppercase letters [a-z]+ · [A-Z]+ ASCII case-specific letters; i ignores the distinction
between 2 and 4 digits \d{2,4} Two to four digits, inclusive
optional "-" -{0,1} Zero or one hyphen
hex digit · 6 hex digits [0-9A-Fa-f] · [0-9A-Fa-f]{6} ASCII hexadecimal digits
letter · letters [A-Za-z] · [A-Za-z]+ One ASCII letter / one or more
space · spaces \s · \s+ One whitespace character / one or more, including line breaks
between 1 and 32 path segment characters 1–32 Unicode code points Excludes slash, backslash, NUL and line breaks
"hello" hello Exact text, safely escaped
one of: a, b [ab] One character from the list
text without: a, b [^ab]* Zero or more characters outside the list
any text .* Any text; s includes line breaks

word character matches an ASCII letter, digit or underscore; word characters matches one or more. Set a length with between 3 and 30 word characters. The shorter word and not word rules still use JavaScript's \w / \W. They aren't every Unicode letter: \w includes _ and excludes é. Use letter / letters to exclude digits and underscores; counts work too, such as 3 letters. Without i, lowercase letters and uppercase letters match only their ASCII ranges. The i flag ignores that distinction and adds JavaScript case-folding equivalents such as K and ſ. Unicode matching is always on: the source checkout accepts u or v, with u as the default. See the full language guide for flags, escaping, limits, and diagnostics.

💻 Bring it to your terminal

With Node.js 22+, install the preview globally if you want the command on your PATH:

npm install --global regex-for-humans@preview
printf 'start "ABC"\n3 digits\nend\n' | regex-for-humans

Or run directly from a clone:

git clone https://github.com/OthmaneBlial/Regex-For-Humans.git
cd Regex-For-Humans
printf 'start "ABC"\n3 digits\nend\n' | node bin/regex-for-humans.js
/^ABC\d{3}$/u

✅ ABC123   ❌ ABC12, ABC1234, abc123

Option What it does
--explain Show each rule's fragment and meaning
--json Structured results on stdout; errors on stderr
--ignore-case Add flag i
--dot-all Add flag s
--flags Select native JavaScript flags; u/v are exclusive
--flags FLAGS Select unique d, g, i, m, s, u, v, y flags
--help Show usage
--target export supported semantics to the named language; see profiles
--version Show the package version

Read UTF-8 rules from a file or stdin. Use -- before a filename starting with -.

--help includes a runnable POSIX-shell example. Exit codes are 0 for success/help/version, 1 for invalid rules or input/output failures, and 2 for invalid command arguments.

🔧 CLI error contract

Malformed UTF-8 is rejected with a message to save the input as UTF-8 and try again; invalid bytes are never replaced silently. This applies to both rules and reverse-mode regex literals. In JSON mode, rule diagnostics retain their codes, invalid arguments use CLI_USAGE, and file/runtime failures use CLI_ERROR, including invalid UTF-8 and stdout write failures. If stderr also fails, the CLI exits nonzero without a diagnostic.

JSON diagnostics can include endColumn, an exclusive one-based UTF-16 column on the same line. The workshop highlights and selects the complete known token; errors without a range retain point navigation.

Control characters and Unicode line separators from rules, arguments and filenames appear as visible escapes in CLI output. JSON decoding restores the original data; displayed regexes still match the original characters.

🔄 Translate a regex back into rules

The 0.1.0-dev.12 preview includes --reverse. Translate a slash-delimited JavaScript regex with u or v:

printf '%s\n' '/^[A-Z]{2}-[0-9]{4}$/u' | npx --yes --package=regex-for-humans@preview regex-for-humans --reverse
start
2 uppercase letter
"-"
4 digit
end

Use --reverse --json for { rules, flags }, matching regexToRules(). Pass the returned flags to compile(rules, { flags }) to preserve native matching and cursor behavior. All eight flags are supported; g/y regexes remain stateful. Text output reports required options on stderr while retaining a successful exit code.

📦 Use the JavaScript library

After npm install regex-for-humans@preview, import the package in an ES module (.mjs, or a project with "type": "module"). TypeScript declarations are included. From a source checkout, use ./index.js instead.

import { compile, regexToRules, toRegExp } from 'regex-for-humans';

const result = compile('start 3 digits\nend');
console.log(result.source);                // ^\d{3}$
console.log(toRegExp(result).test('123'));  // true
console.log(result.segments);              // Each fragment + explanation

const reverse = regexToRules(/^[A-Z]{2}-\d{4}$/u);
console.log(reverse.rules);                 // start\n2 uppercase letter\n"-"\n4 digit\nend
console.log(reverse.flags);                 // Flags to pass back to compile()

TypeScript accepts cached compile metadata: toRegExp({ source, flags }). Both fields must be strings; explanation segments are not needed or read. Complete compile results remain accepted.

compile("digit", { flags: undefined }) uses the default u flag, just like omitting flags. Its TypeScript option type accepts this with exactOptionalPropertyTypes enabled. toRegExp() metadata still requires string flags.

regexToRules() also accepts genuine regexes from other JavaScript contexts, such as iframes or Node's vm, and leaves their lastIndex unchanged. It translates the stored native pattern and flags; subclass or own-property metadata overrides do not change the translation. Matching methods and custom Symbol.match getters are not called.

Unicode escapes can include leading zeros: /^\u{00000041}$/u translates to start, "A", end on separate lines. The same escapes work in character lists and literal groups; the regex source still has a 16,384-code-unit limit.

🎛️ Flags with a purpose

Flag How to enable it What changes
u Default, or explicit { flags: 'u' } Unicode code-point matching; emoji are single matching atoms
i compile(rules, { flags: 'i' }) or --ignore-case Native JavaScript case folding, including its Unicode equivalents
s compile(rules, { flags: 's' }) or --dot-all any character / any text can include line breaks
m { flags: 'm' } or line start / line end Native line anchors; input anchors remain absolute
d { flags: 'd' } Native match and capture indices
g { flags: 'g' } Repeated native calls advance lastIndex
y { flags: 'y' } Match at lastIndex; search stops at the first gap
v { flags: 'v' } Native Unicode-set class escaping and complement semantics

In the preview: all eight flags are accepted in any order and returned canonically as dgimsuvy. Duplicates and combining u with v are errors; omitting both selects u. For example, use { flags: 'dgiv' } or --flags dgiv. Reverse translation preserves the options without changing the input regex's lastIndex. The workshop resets each example to position 0 and lists up to 100 search matches; copied g/y regexes remain stateful. Mixed input/line anchors work without weakening absolute input boundaries. Unsupported runtime capabilities fail explicitly. Available in npm 0.1.0-dev.12.

In the preview: select v for one of strings: "a", "ab", "" or unicode property "RGI_Emoji". Native sets try longer members first, regardless of list order; later rules can require a shorter member. Empty strings are allowed. Use string "ab" inside a class. String properties and empty/multi-code-point members cannot be complemented. Available in npm 0.1.0-dev.12.

In the preview: native nested sets use character set union {, character set intersection { and character set subtraction {, closed by }. Each line is one character, range, class, property, string set or nested set. Intersection keeps shared members; subtraction removes right-hand members from the first operand. Counts and lazy apply to the whole block. not follows native structural string restrictions; an empty union matches nothing. Select v; Available in npm 0.1.0-dev.12. Set syntax and examples.

Local group flags. Open group with flags "i" {, put "hello" inside and close with } to generate (?i:hello). It accepts HELLO while later rules keep their original case behavior. Use "im-s" to enable local case folding and line anchors while disabling dot-all. Nested scopes restore enclosing options, and captures can go inside the block. Scoped syntax and examples.

Check the receiving runtime. Syntax support alone is insufficient: verified Chrome, Firefox and WebKit Unicode modes pass; tested Node 22 lacks the syntax and Node 25/26 have native matching defects, so compilation reports UNSUPPORTED_TARGET_FEATURE. Cached toRegExp({ source, flags }) also checks actual scoped behavior in the supplied mode after native construction; invalid native syntax retains SyntaxError. Unsupported scopes are never approximated. See distribution status for the published version.

🛠️ Make yourself at home

Run the workshop locally:

npm ci
npm run build
npm run serve

Open http://127.0.0.1:4174/. Go to error jumps to a reported source position.

To choose an available port automatically, use npm run serve -- 0 and open the URL printed by the server. Directory URLs automatically redirect to their trailing-slash form, preserving query strings so nested pages and their relative assets load correctly.

Run all quality checks locally:

npm ci
npm exec -- playwright install firefox webkit
npm run verify

This runs lint, formatting, types, docs, Node tests, the Pages build, clean-consumer package checks, desktop/mobile Chromium tests, Firefox/WebKit compatibility smoke tests, and a dependency audit. GitHub CI is disabled. The full gate uses installed Chrome plus Playwright Firefox and WebKit.

If Chrome is unavailable, install all three Playwright engines after npm ci and use bundled Chromium for the desktop/mobile suites:

npm exec -- playwright install chromium firefox webkit
CI=1 npm run verify

CI=1 selects the bundled browser locally; it does not enable GitHub Actions.

🧭 Know the boundaries

Output targets JavaScript RegExp. Raw regex is not accepted as rule text; regexToRules() translates only the documented supported subset back into rules. Free-form English, u-mode empty character classes and forward/open references remain unsupported. The workshop tests examples in a time-limited worker; a copied regex needs its own execution safeguards. Read the security model.

💬 Questions you might have

Is this an AI regex generator? No. A deterministic parser maps a documented vocabulary to an AST, then emits native regex and explanations. The same rules and options give the same result. Unknown syntax fails explicitly.

Will it parse every regex? No. Unsupported syntax returns a diagnostic and preserves workshop edits. It never removes a capture, assertion or alternative to manufacture a translation. Captures and nested groups are supported in the checkout; the compatibility table lists the remaining limits.

Does a passing example prove the pattern is safe? No. Examples check selected behavior. Source and repetition limits, plus the worker's deadline, protect the workshop interaction. They do not guarantee that every copied regex is fast in another program.

Is digit every Unicode numeral? No: \d is ASCII 0–9. letter is [A-Za-z], and word follows native \w semantics. The u flag does not turn these into universal Unicode categories.

What are the limits? Rules: 16,384 UTF-16 code units, 200 lines, at most 1,000 for bounded repetition, and 64 group levels. Workshop: 100 examples, 2,048 UTF-16 units per example, and a 1,200 ms worker deadline. An emoji normally uses two UTF-16 units even though u matches it as one code point.

Result batches also have limits: 1,000 matches, 20,000 captures and 1,048,576 UTF-16 units of result text. When output is too large, the whole run stops; your rules and examples remain editable.

Can I use it offline? The library and CLI run locally. After dependencies are installed, you can build and serve the workshop locally. The hosted site needs a connection to load; no offline caching or installable PWA is claimed.

Where should I report a problem? Use GitHub issues for reproducible bugs and syntax requests. Include rules, flags, input, expected behavior and runtime version. Report security issues privately using SECURITY.md.

🗺️ Explore the project

Guide What you will find
Language Exact grammar, groups, references, escaping, flags and diagnostics
Complex examples Complete patterns and explanations for four larger formats
Architecture Parser → AST → compiler → API/CLI/workshop
Compatibility Supported constructs and verified runtimes
Testing Reproducible commands and scoped verification records
Security model Trust boundaries, worker isolation and known limits
Distribution Published npm, release and hosted-site evidence
Current roadmap Implemented milestones and the next priorities
Competitor gaps Source-backed comparison and remaining capability gaps
Contributing Setup, scope and contribution conventions

Release validation: the verification record separates compiler/CLI checks, Chromium desktop/mobile workflows, Firefox/WebKit checks, homepage tests, clean JavaScript/TypeScript consumers and dependency auditing. Node 22 consumers are checked separately. Human usability, translation and screen reader reviews remain open.

Structural risk review

Open Review the pattern in the local workshop for source-linked notes on nested/adjacent variable repetitions, overlapping alternatives, broad wildcards, line anchors and large generated patterns. Hover connects the rule, regex fragment, explanation and diagram without moving the caret; selecting a note returns to its source line. Source, flag, recipe and group edits refresh the review.

The shared analyze(rules, { flags }) API returns canonical flags, typed findings with source locations/spans and explicit limitations. Positive class/range witnesses cover selected overlaps; an unknown set is not treated as proven disjoint. This is heuristic analysis: it may miss expensive patterns or report false positives, and no findings does not prove performance safety. Analysis does not run matches or measure backtracking. Example matching keeps its isolated worker and deadline.

See the structural risk review contract.

Structural diagrams

Move the source cursor or select generated regex to follow the structure; hover leaves the source caret and scroll position unchanged. Enter/Space on a diagram node returns to its rule. Long labels retain complete explanations in titles. Read the structural diagram contract for the API, display rules and limits.


Small language. Clear meaning. Happy matching. 🥳

📖 Language · 🧪 Testing · 🤝 Contributing · 📝 Changelog · ⚖️ MIT

Security issue? Use the private process in SECURITY.md.

Releases

Packages

Contributors

Languages