\0: matching the null character safely
\0 matches the null character U+0000, provided it is not followed by another digit. When a digit does follow, the sequence becomes a legacy octal escape instead.
At a glance
- Character
- U+0000, the null character
- Unambiguous spellings
- \x00 and \u0000
- Followed by a digit
- \01 is a legacy octal escape without u, and a SyntaxError with u
- Matched by \s
- no, null is not whitespace
- Matched by the dot
- yes, null is not a line terminator
- Where it turns up
- null terminated exports, fixed width dumps and binary safe delimiters
In detail
On its own the escape is straightforward: \0 matches one null character. The complication is that the sequence is only null while nothing numeric follows. Write \01 and you no longer have a null followed by a one; you have a legacy octal escape meaning U+0001, which matches a completely different character and does so without any warning.
Turning on the u flag makes that ambiguity an error rather than a surprise. Under u, \01 throws a SyntaxError about an invalid decimal escape, which is the right outcome for a sequence whose meaning nobody can guess from reading it. If a pattern with octal escapes has to keep working, it needs rewriting before the flag goes on.
The safest habit is to avoid \0 entirely and write \x00 or \u0000, both of which have a fixed length and cannot absorb the next character. Those spellings also read as deliberate, which matters in a pattern where a null is genuinely expected rather than a typo.
Nulls are worth matching more often than people expect. They separate records in some export formats precisely because they cannot appear in ordinary text, they pad fixed width fields in older systems, and their unexpected presence in a supposedly plain text value is usually the first sign that the encoding step went wrong somewhere upstream.
Examples
/\0/.test("\u0000"); // true
/\x00/.test("\u0000"); // true
/\u0000/.test("\u0000"); // true
"a\u0000b".split(/\x00/); // ["a", "b"]/\01/.test("\u0001"); // true, this is an octal escape for U+0001
/\01/.test("\u00001"); // false, it is not null followed by a one
new RegExp("\\01", "u"); // SyntaxError: Invalid decimal escapeThings that catch people out
- \0 only means null while no digit follows. \01 is an octal escape for a different character entirely, and nothing in the pattern hints at the change.
- Adding the u flag to a pattern containing an octal escape throws. That is the correct behaviour and it will still break a deploy if the flag is added without reading the pattern first.
- Null characters are not whitespace, so a trim will not remove them and a value that looks empty can still carry them.
Try it: Regex Tester
Type a pattern and a test string, watch every match highlight as you go, read a plain English breakdown of each token, and check the numbered and named groups it captured.
Regex Tester
LOCAL · Browser-OnlyTest and debug regular expressions with live matching and highlights
Related Regex syntax
All regex syntax →\xhh: matching a character by two hex digits
\xhh takes exactly two hex digits and covers U+0000 to U+00FF. Writing four by mistake gives a two digit escape followed by literal text.
\uhhhh: matching a character by code unit
\uhhhh takes exactly four hex digits and matches one UTF-16 code unit, so anything above U+FFFF needs a surrogate pair or the braced form.
The u flag: Unicode mode
What the u flag changes about how a pattern is parsed, the escape forms it unlocks, and the previously tolerated syntax it turns into a hard error.
\u{...}: code point escapes that need the u flag
The braced escape addresses any code point up to 10FFFF and makes quantifiers apply to whole characters, but only when the u flag is set.
Escaping metacharacters: which ones, and where
Twelve characters need escaping outside a character class and only four inside one. User input needs an escape function before it goes near new RegExp.
Regex for email addresses: what can and cannot be validated
No regular expression fully validates an email address. Here is what the built in preset accepts, what it rejects, and the only check that settles it.
Tools for this
- Regex Tester Free online regex tester - test and debug regular expressions with live matching and highlights
- Regex Playground Regex playground with live match highlighting, named groups, find and replace, and shareable links