Regex Tester & Debugger

Share:

Test and debug regular expressions in real time — with match highlighting, capture groups, replace mode and a built-in pattern library. Free, no signup.

RT-DEV-009 · Developer Tools

Regex Tester Tool

Flags:
Your test string appears here with matches highlighted…
Advertisement
After results · AD-W1 Responsive · Post-tool — peak engagement

How to Use the Regex Tester

Enter your regex pattern

Type your pattern into the pattern field between the two forward slashes. The syntax /pattern/flags is standard JavaScript format. Your results update live on every keystroke — no button press required.

Paste your test string

Paste or type the text you want to test against in the Test String field. Matches are highlighted in real time with colour-coded marks. Multiple matches show different highlight colours cycling through up to five distinct shades.

Toggle flags as needed

Use the flag buttons to change matching behaviour: g to find all matches (not just the first), i for case-insensitive matching, m to make ^ and $ match line boundaries, and s (ES2018) to make the dot match newlines.

Use the Quick Patterns library

Click any pattern in the Common Patterns panel below the tool to instantly insert it and test it against your string. The library includes patterns for SG NRIC, postal codes, phone numbers, emails, IPv4 addresses and more — useful starting points to study or adapt.

Advertisement
After how-to · AD-W2 Responsive

Regular Expressions — The Universal Language of Pattern Matching

Regular Expressions: From Zero to Useful in 10 Minutes

A regular expression (regex) is a sequence of characters that defines a search pattern. At its most basic, a regex is just a literal string: the pattern hello matches the exact text "hello". From there, the power multiplies rapidly. The dot metacharacter . matches any single character except a newline. Quantifiers control repetition: * means zero or more, + means one or more, and ? means zero or one. Character classes such as [a-z] or [0-9] match any character within the specified set, while anchors ^ and $ pin a match to the start or end of a line. Alternation with the pipe character | works like a logical OR, and parentheses () create capture groups that let you extract sub-portions of a match for reuse.

The practical use cases are vast. Form validation — checking that an email field contains an @ and a domain — is one of the first tasks every developer encounters. Log parsing is another evergreen use: extracting IP addresses, timestamps, and HTTP status codes from server logs with a single regex pass is many orders of magnitude faster than splitting strings manually. Text cleaning — removing excess whitespace, stripping HTML tags, normalising phone number formats — all become concise one-liners with the right regex. Regex is deeply embedded in every major programming language: JavaScript (ECMAScript spec), Python (re module, PCRE-like), PHP (PCRE), Java (java.util.regex), Go (RE2 engine), and SQL (REGEXP or SIMILAR TO depending on the dialect). PCRE, Perl Compatible Regular Expressions, is the dominant server-side standard and supports features beyond the ECMAScript spec such as atomic groups, possessive quantifiers, and recursive patterns. JavaScript's regex follows the ECMAScript standard, which has been growing rapidly: ES2018 added named capture groups, the s dotAll flag and lookbehind assertions; ES2021 added the d flag for match indices.

Singapore government digital services are a practical example of regex in production. The NRIC number format — a letter prefix (S, T, F, G, or M), seven digits, and a checksum letter — is validated by every form in systems from CPF to SingPass. The postal code system uses exactly six digits, making \d{6} the simplest valid postal code pattern. Phone number parsing must handle both the +65 country code prefix and the eight-digit local format beginning with 6, 8 or 9.

Capture Groups vs Non-Capturing Groups: When and Why They Matter

A capturing group (abc) does two things: it groups part of the pattern for quantifier purposes, and it creates a numbered reference — $1 in a replace string, or \1 as a backreference within the pattern itself. Backreferences are powerful for matching repeated patterns: the pattern (['"]).*?\1 matches a string delimited by either single or double quotes because \1 requires the closing delimiter to match whatever the opening one was.

When you only need the grouping behaviour without creating a reference, use a non-capturing group (?:abc). This is more efficient and avoids polluting your group index count. Named capture groups, added in ES2018, take readability further: (?<year>\d{4})-(?<month>\d{2}) lets you access matches as result.groups.year instead of result[1] — much clearer when the pattern has many groups. For context-dependent matching without consuming characters, use lookahead (?=abc) — which asserts that what follows matches the pattern — or lookbehind (?<=abc), which asserts what precedes. A practical example: the pattern \d+(?= dollars) matches a number only if it is immediately followed by the word " dollars", but the " dollars" part itself is not included in the match.

"One well-crafted regex can replace 50 lines of string manipulation code — but one poorly designed regex can bring down a server through catastrophic backtracking."

Regex in Production: Common Patterns Used by ASEAN Developers Daily

Across the ASEAN developer community, several regex use cases appear constantly. Singapore NRIC validation is a common interview question: the simplified pattern [STFGM]\d{7}[A-HJKZ-RT-WXY] validates the format, but the actual checksum requires a modulo-11 computation in JavaScript — regex alone cannot confirm validity. Malaysian mobile numbers begin with +60 followed by a 1 and then seven or eight digits, giving the pattern (\+?60|0)1\d{7,8}. Indonesian NIK (Nomor Induk Kependudukan) is a 16-digit national identity number validated by \d{16} for format, with the first six digits encoding province, city and district codes.

One important caution: do not use regex to parse HTML or XML in production. The recursive, context-free structure of HTML cannot be fully described by a regular language, and regex parsers will fail on nested tags. Use a proper DOM parser such as DOMParser in JavaScript or SimpleXML in PHP instead. For database work, SQL LIKE supports simple wildcard patterns (% and _), but most modern databases — MySQL, PostgreSQL, SQLite — support full regex via REGEXP or ~ operators for more expressive pattern matching. OWASP guidance on input sanitisation recommends a whitelist approach with regex: define the exact set of allowed characters rather than trying to blacklist dangerous ones. For web application security, anchoring patterns with ^ and $ is critical — without anchors, a pattern can match a substring of a longer, malicious input and produce a false validation pass.

10 Facts About Regular Expressions

01

Regular expressions were first described by mathematician Stephen Kleene in 1951 as a formal notation for describing "regular sets" in automata theory.

02

JavaScript's regex engine uses a Non-deterministic Finite Automaton (NFA) algorithm — which can exhibit catastrophic backtracking on pathological patterns like (a+)+b.

03

The g (global) flag in JavaScript changes the behaviour of test() — it advances the lastIndex property, which can cause alternating true/false results if not reset between calls.

04

PCRE (Perl Compatible Regular Expressions) is used by PHP, Python, and most server-side languages — it supports more features than JavaScript's ECMAScript regex, including atomic groups and possessive quantifiers.

05

Singapore's NRIC checksum algorithm uses a modulo-11 formula on the 7 digits — a regex alone cannot validate the checksum, requiring additional JavaScript logic.

06

Email validation via regex is notoriously difficult — the RFC 5321 specification allows characters like "user name"@example.com that most regex patterns fail to handle correctly.

07

The dot . metacharacter matches any character except newline by default — the s (dotAll) flag, added in ES2018, makes . also match newline characters.

08

Named capture groups ((?<year>\d{4})) were added to JavaScript in ES2018 — they improve regex readability and allow accessing groups by name instead of index.

09

Google's RE2 library guarantees linear-time regex matching — unlike backtracking NFA engines — making it safe for user-supplied patterns. It is used in Go's regexp package.

10

Stack Overflow was taken offline for 34 minutes in 2016 due to a catastrophic backtracking regex in its markdown parser — exposing the real-world consequences of unsafe regex patterns.

Frequently Asked Questions

  • g (global) finds all matches in the string rather than stopping after the first. i (case insensitive) makes the match ignore upper/lower case differences. m (multiline) changes the behaviour of ^ and $ so they match the start and end of each line, not just the whole string. s (dotAll), added in ES2018, makes the dot . metacharacter also match newline characters, which it normally ignores.
  • + is a quantifier meaning "one or more" — the preceding element must appear at least once. * means "zero or more" — the preceding element can be completely absent. So \d+ requires at least one digit, while \d* can match an empty string. For most validation use cases, + is the correct choice because you want at least one character to be present.
  • Escape the dot with a backslash: \. matches a literal period character. Without the backslash, . is a metacharacter that matches any character except newline. This is a very common mistake when writing patterns for file extensions (\.js$) or IP addresses (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).
  • A capture group is a portion of your pattern wrapped in parentheses (). It serves two purposes: grouping for quantifiers, and capturing the matched text for later use. Each group is numbered from left to right starting at 1. In the Match Details table on this tester, groups are shown per match so you can see exactly what each one captured. In a replace string, reference them as $1, $2, etc. Named groups using (?<name>...) can be referenced as $<name>.
  • The pattern [STFGM]\d{7}[A-HJKZ-RT-WXY] validates the structural format: a valid prefix letter (S for Singapore citizens born before 2000, T for citizens born 2000+, F and G for foreigners, M for newer foreign passes), exactly seven digits, and a valid checksum letter. However, regex alone cannot confirm the NRIC is genuine — the checksum letter is derived from a modulo-11 algorithm applied to the seven digits. You need additional JavaScript to compute and verify the checksum.
  • Catastrophic backtracking occurs when an NFA-based regex engine (like JavaScript's) tries an exponential number of match paths on a failing input. The classic example is (a+)+ — for an input like "aaaaaaaaab" with no final match, the engine explores every possible way to group the "a" characters before giving up, taking exponential time. This is a real security vulnerability: user-supplied patterns with nested quantifiers can be weaponised as a denial-of-service attack called a ReDoS (Regular Expression Denial of Service).
  • Greedy quantifiers (*, +, {n,m}) match as many characters as possible. Lazy quantifiers (*?, +?, {n,m}?) match as few as possible. For example, with the input <b>bold</b> and <i>italic</i>, the greedy pattern <.*> matches everything from the first < to the last >. The lazy pattern <.*?> matches each individual tag. Lazy matching is much more common when parsing HTML-like structures.
  • Enable the m (multiline) flag to make ^ and $ match the start and end of each line. To make the dot match newlines (so a pattern can span multiple lines), also enable the s (dotAll) flag. Without s, you can work around the limitation with the character class [\s\S] which matches any whitespace or non-whitespace character — effectively matching everything including newlines. For example, [\s\S]*? is the multiline equivalent of a lazy .*?.
  • In the Replace tab, use $1, $2, etc. to insert the text captured by each group. For example, with pattern (\w+)\s(\w+) and replace string $2 $1, the words "first last" would become "last first". $& inserts the entire matched string, $` inserts the text before the match, and $' inserts the text after. For named groups defined as (?<name>...), use $<name> in the replace string.
  • 100% free, forever. No account, no subscription, no hidden limits. RECATOOLS is funded by contextual advertising, not paywalls. All regex processing runs entirely in your browser using the JavaScript engine — no data leaves your device. The tool works with or without ad consent enabled.

Related News

You may be interested in these recent stories from our newsroom.

View all news →
Advertisement
Pre-footer · AD-W3 728 × 90

75 more free tools

Calculators, converters, security tools — no signup.