JSON Value Token Regex
Matches a single JSON scalar value: a double-quoted string, a JSON-formatted number, or one of the literals true, false, or null.
Regex Pattern
^(?:"(?:[^"\\]|\\.)*"|-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?|true|false|null)$Pattern Breakdown
Hover over a token to see what it does.
| Token | Meaning |
|---|---|
| "(?:[^"\\]|\\.)*" | A JSON string: an opening quote, any run of non-quote/non-backslash characters or backslash-escaped sequences, then a closing quote |
| [^"\\] | Any character inside the string that is not a quote or a backslash |
| \\. | An escaped character such as \n, \", or \\ |
| -? | An optional leading minus sign for negative numbers |
| (?:0|[1-9]\d*) | The integer part: either a single zero or a non-zero digit followed by more digits (no leading zeros) |
| (?:\.\d+)? | An optional fractional part |
| (?:[eE][+-]?\d+)? | An optional exponent part |
| true|false|null | The three JSON literal keywords |
Detailed Explanation
What it does
This pattern validates that a string is a single, well-formed JSON scalar value on its own, not an object or array. It accepts JSON strings with proper escape sequences, JSON numbers with the strict no-leading-zero rule, and the literals true, false, and null.
Why it works
Each alternative in the top-level group models one JSON value grammar rule exactly: the string branch mirrors the JSON spec's escape handling, the number branch enforces that integers either are zero or start with a non-zero digit, and the literal branches are simple fixed keywords. Anchoring with ^ and $ ensures the entire input is one value, not just a value embedded in a larger string.
Common use cases
- Validating a single form field or config value before wrapping it into a JSON payload
- Highlighting JSON value tokens in a syntax highlighter or lightweight JSON viewer
- Quick sanity-checking of extracted values in a log-scraping or config-templating tool
- Building a hand-rolled JSON tokenizer for teaching or debugging purposes
Edge cases
- Leading zeros like 0123 are correctly rejected since the integer branch disallows them
- Escaped quotes inside strings, like "say \"hi\"", are matched because \. consumes the backslash and the escaped quote together
- Negative zero, -0, is accepted since the number grammar allows an optional minus before a single zero
- Scientific notation such as 1.5e10 or 2E-3 is matched by the optional exponent group
Limitations
- This pattern only validates a single scalar value and does not handle JSON objects or arrays
- It does not verify that a string's escape sequences (like \uXXXX) are valid Unicode code points
- Extremely large numeric literals are matched syntactically but may lose precision when parsed as a JavaScript number
Interactive Tester
Edit the pattern or text below — matching runs live in your browser.
Test Cases
Editable — add your own inputs to see if they pass.
| Input | Expected | Result | |
|---|---|---|---|
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass |
Language Variants
Production-ready examples in 12 languages.
const jsonValueRegex = /^(?:"(?:[^"\\]|\\.)*"|-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?|true|false|null)$/;
console.log(jsonValueRegex.test('42')); // trueCommon Mistakes
Allowing leading zeros in the integer part, e.g. writing \d+ instead of (?:0|[1-9]\d*), which lets invalid numbers like 007 pass
Fix: Use (?:0|[1-9]\d*) so a lone zero is allowed but multi-digit numbers can't start with zero
Forgetting to allow escaped characters inside strings, causing valid JSON strings with \" or \\ to fail
Fix: Add the \\. alternative alongside [^"\\] so any backslash-escaped character is consumed as a unit
Anchoring only with $ or only with ^, which allows partial matches inside a larger string
Fix: Always pair ^ and $ (or use full-string matching APIs) when validating a value, not just extracting one
Performance Notes
- The alternation is ordered so common cases (strings, then numbers) are tried early, but all branches are still checked linearly with no exponential blowup
- The string branch's (?:[^"\\]|\\.)* can backtrack character-by-character on malformed input, but it's still linear because each branch consumes at least one character
- For validating many values in a loop, compile the RegExp once outside the loop rather than re-creating the literal each time
Browser Compatibility
| Engine | Supported | Notes |
|---|---|---|
| Chrome | Yes | — |
| Firefox | Yes | — |
| Safari | Yes | — |
| Edge | Yes | — |
| Node.js | Yes | — |