skip to content

What does the dot (.) match in Java regex, and how does it differ from a character class with respect to line terminators and the DOTALL flag?

level: middleimportance: must knowfreq 71%

answer

  1. Dot = any char EXCEPT line terminators
  2. DOTALL / (?s) makes dot match newlines
  3. Negated class [^x] DOES match newline
  4. [\s\S] = truly any character
  5. Dot inside [ ] is a literal period

basics

~20 s

By default the dot matches any single character EXCEPT a line terminator like \n. With the DOTALL flag it matches every character including newlines. A character class like [^x] matches newlines unless you exclude them.

solid answer

~40 s

The dot (.) is a built-in pattern that matches any one character except a line terminator by default; line terminators include \n, \r, \r\n, and a few Unicode ones. To make the dot also match line terminators, compile with Pattern.DOTALL (or use inline (?s)). This contrasts with character classes: a negated class such as [^a] DOES match a newline, because class negation does not exclude line terminators the way the dot does. So if you build a class to mean "any character" you typically write [\s\S] or [\d\D], which truly matches everything including newlines without needing DOTALL. Inside a character class the dot loses its wildcard meaning and is a literal period, e.g. [.] matches a dot.

go deeper

for a junior

Knows the dot matches any character and roughly that newlines are special.

for a middle

States the dot excludes line terminators by default and that DOTALL/(?s) changes it; knows the dot is literal in a class.

for a senior

Uses [\s\S] vs DOTALL deliberately, distinguishes DOTALL from MULTILINE, and avoids greedy .* pitfalls.

for a principal

Considers ReDoS/performance of dot-star, defines team conventions for multi-line matching, and reasons about Unicode line terminators.

## The dot is a wildcard, not a class member The **dot** `.` is a metacharacter that matches **any single character** — with one default exception: a **line terminator**. A line terminator is a character (or pair) that ends a line: line feed `\n`, carriage return `\r`, the `\r\n` pair, plus next-line ` `, line separator `
`, and paragraph separator `
`. So by default `.` matches letters, digits, spaces, punctuation — but **not** a newline. This is why a pattern like `a.b` will not span across a line break by default. ## DOTALL: make the dot match everything To make `.` also match line terminators, compile with the flag `Pattern.DOTALL` (sometimes called "single-line mode"), or prepend the inline flag `(?s)`: ```java Pattern.compile("a.b", Pattern.DOTALL); // dot now matches \n too Pattern.compile("(?s)a.b"); // equivalent inline form ``` Do not confuse DOTALL with `MULTILINE`/`(?m)`, which is unrelated: MULTILINE changes what `^` and `$` anchor to (start/end of each line), **not** what `.` matches. ## The dot vs character classes This is the crucial contrast for this topic: - The **dot** excludes line terminators by default. - A **negated character class** does **not**. `[^a]` matches any character that is not `a`, **including** `\n`. Therefore, to write a class meaning "absolutely any character including newlines" without DOTALL, the idiom is `[\s\S]` (whitespace or non-whitespace = everything) or equivalently `[\d\D]`, `[\w\W]`. These are common because they are local (they don't require a compile flag affecting the whole pattern). ## The dot inside a class is literal Inside square brackets the dot loses its wildcard power and is just a period: `[.]` matches a literal dot, the same as `\.` outside a class. So `[.,;]` matches one of dot, comma, or semicolon, all literal. ## Why this matters in practice Greedy `.*` is a frequent source of bugs and even ReDoS-style slowdowns; knowing that `.` stops at newlines by default helps explain why a multi-line text isn't fully captured, and choosing `[\s\S]*` vs `(?s).*` is a deliberate decision. For matching everything reluctantly, `[\s\S]*?` or `(?s).*?` is preferred. ## Java source escaping The dot needs no backslash to be a wildcard; to match a literal dot outside a class use `\.` which is `"\\."` in Java source, or `[.]`. ## Deriving the answer Two anchors of knowledge: (1) dot = any char EXCEPT line terminators unless DOTALL; (2) negated classes DO include newlines, so `[\s\S]` is "truly any char". From these you can reason about every multi-line matching question.

  • What is the difference between DOTALL and MULTILINE?
    DOTALL ((?s)) makes the dot match line terminators too. MULTILINE ((?m)) instead makes ^ and $ match at the start/end of each line rather than only the whole input. They are independent flags solving different problems.
  • How do you match any character including newlines without setting a flag?
    Use a negated-pair class like [\s\S] (whitespace or non-whitespace = everything). Unlike the dot, a negated/union class is not limited to non-line-terminators, so it matches newlines locally.

saying these in an interview costs you the question

  • Thinking the dot always matches newlines
  • Confusing DOTALL with MULTILINE (^/$ behavior)
  • Assuming [^a] excludes newlines like the dot does
  • Escaping the dot inside a class as [\.] (unnecessary; [.] suffices)

context