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?
answer
- Dot = any char EXCEPT line terminators
- DOTALL / (?s) makes dot match newlines
- Negated class [^x] DOES match newline
- [\s\S] = truly any character
- Dot inside [ ] is a literal period
basics
~20 sBy 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 sThe 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
Knows the dot matches any character and roughly that newlines are special.
States the dot excludes line terminators by default and that DOTALL/(?s) changes it; knows the dot is literal in a class.
Uses [\s\S] vs DOTALL deliberately, distinguishes DOTALL from MULTILINE, and avoids greedy .* pitfalls.
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)