Regex Works in the Tester but Not in My Code? 6 Reasons and Fixes
A regex that matches in a tester but fails in JavaScript, Python or Java usually has lost backslashes, different flags or engine differences. How to fix it.
The short answer
A regex that works in a tester but fails in your code is almost never a wrong pattern. It is usually one of four things: backslashes eaten by your programming language's string rules, missing or different flags, a regex engine that does not support a feature (Python, for example, uses (?P<name>...) for named groups), or a global regex being reused between calls. The Regex Tester uses JavaScript's own regex engine, so a pattern that works there will work in JavaScript once it is written into your code correctly.
What the tester actually runs
Before debugging, it helps to know exactly what you tested:
- Pattern box: you type the raw pattern, without slashes, for example
\d{4}-\d{2}. It is passed to JavaScript'snew RegExp(pattern, flags)as typed, so you never need to double the backslashes there. - Flags box: up to six letters, for example
g,giorgm. Withg, every match is listed; without it, only the first. - Results: each match is highlighted in the test string, and capture groups are listed under each match.
So the tester shows how a pattern behaves in JavaScript with those exact flags. Everything below is about what changes when you move it into real code.
Cause 1: Backslashes disappear inside strings
This is the most common reason. In most languages, a backslash inside a normal string starts an escape sequence, so the string loses it before the regex engine ever sees it.
In JavaScript, if you build the regex from a string:
new RegExp("\d+")becomes the patternd+, which matches the letter d. Running it on "a1d" matches "d", not "1".new RegExp("\\d+")becomes\d+, which matches digits as intended.
Fixes for each language:
| Language | Write the pattern as |
|---|---|
| JavaScript (literal) | /\d+/ (no doubling needed) |
| JavaScript (string) | new RegExp("\\d+") |
| Python | r"\d+" (raw string) |
| Java, C#, Go (normal strings) | "\\d+" |
| C# verbatim string | @"\d+" |
| Go raw string | a backtick-quoted string, with single backslashes |
| JSON config files | "\\d+" |
In Python, always use raw strings (r"...") for regex. Recent Python versions warn about "\d" in a normal string, and some escapes such as "\b" silently turn into a different character (a backspace), so a word-boundary pattern stops matching without any error.
Quick test: print the pattern from your code (console.log(re.source) in JavaScript, print(pattern) in Python). If the printed pattern does not look exactly like what you typed in the tester, the string escaping is the problem.
Cause 2: Different flags
The flags box in the tester is easy to forget. Common mismatches:
- Case: "Hello hello" with pattern
hellofinds one match, but two with theiflag. - Start and end of line:
^and$match the start and end of the whole text unless them(multiline) flag is on. On "line1" followed by "line2" on the next line,^line2$finds nothing withoutm, and matches with it. - Dot and new lines:
.does not match a line break unless you use thesflag.a.bdoes not match "a", line break, "b" without it. - All matches: in JavaScript,
"text".match(/x/)returns the first match only; you need thegflag (ormatchAll) for all of them.
Python spells flags differently: re.I, re.M and re.S, passed as an argument, for example re.findall(r"^line2$", text, re.M).
Cause 3: The other language's regex engine is different
Regex is not one standard. JavaScript, Python, Java, .NET, PHP (PCRE) and Go each support slightly different features. A pattern tested in JavaScript can fail elsewhere, and vice versa.
| Feature | JavaScript | Python re |
|---|---|---|
| Named group | (?<year>\d{4}) | (?P<year>\d{4}) |
| Lookbehind whose alternatives differ in length ("$" or "USD ") | Works | Error: needs fixed width |
| Flag for dot matches new line | s | re.S |
We checked both rows in Python 3.13: (?<year>...) raises "unknown extension", and the alternating lookbehind raises "look-behind requires fixed-width pattern". The same patterns work in JavaScript.
Other engines have their own limits. Go's standard regexp package, for example, does not support lookarounds or backreferences at all. If you are not writing JavaScript, test the final pattern in your target language before relying on it.
Cause 4: A reused global regex in JavaScript
A JavaScript regex with the g flag remembers where its last match ended (its lastIndex). If you call .test() repeatedly with the same regex object, results alternate:
const r = /cat/g; then r.test("cat") three times returns true, false, true.
The second call starts searching after the first match, finds nothing, and resets. This causes validation code that passes one input and fails the next identical one.
Fix: remove the g flag when you only want a yes/no answer, or create the regex inside the function so it starts fresh each time.
Cause 5: The test string is not the real input
The tester only sees what you paste. Real input may differ:
- Windows line endings: text from files may have a carriage return before each line break, so
$sits after an invisible character. Use\r?$or strip the\rfirst. - Leading or trailing spaces: a form value " 560001 " fails
^\d{6}$. Trim input before matching. - Unicode look-alikes: curly quotes, non-breaking spaces and full-width digits do not match
',or\dpatterns written for plain ASCII text. - Whole string versus part:
\d{6}finds six digits anywhere, so "1234567" passes. Use^\d{6}$for an exact match. The guide to regex for Indian mobile numbers, PIN codes and PAN has anchored, tested examples.
Cause 6: You are replacing, not matching
If matching works but the replacement output is wrong, check the replacement syntax. JavaScript uses $1 for group 1 and $<name> for named groups. Python uses \1 or \g<name>. To try replacements before writing code, use Find and Replace with Use regex ticked; it uses the same JavaScript $1 syntax. For more on groups, see find and replace with regex capture groups.
A debugging routine that works
Your pattern and test text stay in your browser; nothing is sent to a server.
Frequently asked questions
Why does my regex work online but not in my code?
Usually because your programming language removed backslashes from the string, the flags differ, or the language's regex engine does not support a feature. Print the pattern from your code and test that exact text.
Do I need to double backslashes in a regex?
Only when the pattern is inside a normal string, such as new RegExp("\\d+") in JavaScript or "\\d+" in Java. Regex literals like /\d+/ and Python raw strings like r"\d+" need single backslashes.
Why does my JavaScript regex test() return true then false?
A regex with the g flag remembers where the last match ended. Calling test() again on the same object starts from there. Remove the g flag for yes/no checks or create the regex each time.
Are named groups the same in Python and JavaScript?
No. JavaScript uses (?<name>...), while Python's re module uses (?P<name>...). Python 3.13 rejects the JavaScript form with an unknown extension error.
Which regex engine does the Lazyblink Regex Tester use?
It uses your browser's JavaScript regex engine, so results match JavaScript code that uses the same pattern and flags.
Put this guide into practice with our free online tool — no signup required.
Open tool