\t: matching tabs in TSV and indented text
\t matches U+0009, the horizontal tab. It is included in \s, which is exactly why a tab separated file must be split on /\t/ and never on /\s+/.
At a glance
- Character
- U+0009 horizontal tab
- Matched by \s
- yes, alongside spaces and line terminators
- Horizontal whitespace only
- [ \t], because JavaScript has no \h
- Tab separated data
- split on /\t/, never on /\s+/
- In a character class
- [\t ] is legal and reads better than a raw tab
- From a string
- new RegExp("\\t") for the same pattern as /\t/
In detail
The reason to write \t rather than typing a tab into the pattern is legibility. A literal tab in a pattern is indistinguishable from a run of spaces in most editors, survives a copy and paste as something else entirely, and disappears entirely when a formatter runs over the file. The escape is two visible characters that always mean the same thing.
The tab separated file is where this matters most. Splitting a row on /\s+/ looks reasonable and quietly destroys the data, because a run of consecutive tabs collapses into one separator and every empty field disappears. The row "a\t\tb" has three fields, the middle one empty, and splitting it on whitespace returns two. Splitting on /\t/ keeps all three.
For indentation you usually want horizontal whitespace only, which JavaScript has no shorthand for. Other engines offer \h; here you write [ \t] by hand. That distinction is what separates trimming the ends of each line from flattening the blank lines between paragraphs, since \s would have eaten the line terminators too.
Inside a character class the escape behaves normally and combines freely, so [\t ,;] is a perfectly readable set of common delimiters. When you are handed a file of unknown provenance, a class like that plus a count of how many fields each row produced is a faster diagnosis than guessing at the format.
Examples
"a\t\tb".split(/\t/); // ["a", "", "b"], the empty field is preserved
"a\t\tb".split(/\s+/); // ["a", "b"], the empty field is gone/^[ \t]+/.exec("\t code")[0].length; // 3
// Trim each line without collapsing the blank lines between them.
" a \n b ".replace(/^[ \t]+|[ \t]+$/gm, ""); // "a\nb"Things that catch people out
- Splitting tab separated data on /\s+/ merges consecutive tabs and silently drops every empty field, which shifts every column after the first gap.
- A literal tab typed into the pattern is invisible and will not survive a formatter or a copy and paste. Write \t instead.
- There is no \h in JavaScript, so a pattern ported from an engine that has it needs [ \t] written out by hand.
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 →\s: every whitespace character it actually matches
The full list behind \s in JavaScript, including the no break space and the byte order mark, plus the one invisible character it deliberately skips.
\n: matching a newline, and the double escape trap
\n matches the line feed character. The trap is building a pattern from a string, where the number of backslashes decides what the engine actually sees.
Regex to trim whitespace, collapse runs and drop blank lines
There is no preset for this one. Four short patterns cover trimming, collapsing, per line trimming and removing blank lines, and each has a different failure.
\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.
\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