\n: matching a newline, and the double escape trap
\n matches U+000A, the line feed. The dot will not match it without the s flag, and when the pattern comes from a string rather than a literal the escape has to be written twice.
At a glance
- Character
- U+000A line feed
- Matched by the dot
- no, not unless the s flag is set
- Matched by \s
- yes
- In a character class
- [\n\r] is the usual line terminator set
- From a string
- new RegExp("a\\nb") to get the same pattern as /a\nb/
- Splitting lines
- /\r?\n/, which handles Windows and Unix text alike
In detail
The escape itself is the least interesting part: it matches one line feed character and nothing else. What makes it worth a page is that a newline is the character the rest of the syntax is defined against. The dot excludes it, ^ and $ under the m flag are positioned by it, and \s includes it, so a great deal of pattern behaviour turns on where the line feeds are.
The double escape problem appears the moment a pattern is built at runtime. In a regex literal you write \n and the engine receives a two character escape sequence. In a string you have to write \\n, because the string literal consumes one backslash before the engine ever sees it. Writing \n in the string is not wrong either, since a real line feed character matches itself, but writing \\\\n gives the engine a literal backslash followed by the letter n and the pattern stops matching anything.
Because the escape is so short it hides in a character class. [\n\r] is the set of the two common line terminators, and [^\n] is the standard any character except a line break, which is what a lot of people actually want when they reach for the dot. Spelling it out is longer and it survives a later flag change.
For splitting text into lines, /\r?\n/ is almost always the right pattern rather than /\n/ alone. Splitting on the line feed by itself leaves a carriage return on the end of every line in a Windows file, and those survive comparison, get written back out, and turn into a bug days later.
Examples
/a\nb/.test("a\nb"); // true
new RegExp("a\\nb").test("a\nb"); // true, the engine sees a\nb
new RegExp("a\\\\nb").test("a\nb"); // false, a literal backslash then n
"a\nb".split(/\n/); // ["a", "b"]"a\nb".match(/a.b/); // null, the dot excludes it
"a\nb".match(/a.b/s)[0]; // "a\nb"
"a\nb".match(/^./gm); // ["a", "b"], m positions anchors by itThings that catch people out
- Building a pattern with new RegExp needs the escape written twice. One backslash too many gives the engine a literal backslash and the pattern quietly matches nothing.
- Splitting on /\n/ alone leaves a carriage return at the end of every line in Windows text, and those invisible characters break equality checks much later.
- Adding \n to a character class does not make the dot elsewhere in the pattern cross a line. Only the s flag or [\s\S] does that.
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 →\r: carriage returns, CRLF and stray line endings
\r matches the carriage return that Windows text puts before every line feed. It is also a line terminator for ^ and $, which not every engine agrees with.
The s flag: dotAll mode
What dotAll changes, why it has no effect at all on character classes, and the [\s\S] idiom that did the same job before the s flag existed.
The m flag: multiline anchors
What multiline mode changes about ^ and $, which line terminators JavaScript counts, and why the m flag never makes the dot match a newline.
\t: matching tabs in TSV and indented text
\t matches the horizontal tab. Splitting a tab separated row on \s+ instead destroys every empty field, and JavaScript has no \h shorthand.
\0: matching the null character safely
\0 matches U+0000, but only while no digit follows it. \01 is an octal escape without the u flag and a syntax error with it, so \x00 is the safer spelling.
\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.
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