skip to content

How does the MULTILINE flag change the meaning of ^ and $ in Java regex, and how do you enable it?

level: middleimportance: should knowfreq 58%

answer

  1. MULTILINE → ^/$ per line
  2. (?m) is the inline flag
  3. Affects only ^ and $
  4. DOTALL/(?s) is for ., not the anchors
  5. \A \z \Z ignore MULTILINE

basics

~20 s

By default ^ and $ match the start and end of the whole input. With the MULTILINE flag they match at the start and end of every line, so they fire after each line terminator inside the text.

solid answer

~50 s

By default Java regex treats the input as a single string: ^ matches only at the start of the input and $ only at the end (or just before a trailing terminator). Turning on MULTILINE changes this so ^ matches at the start of the input and immediately after every line terminator, and $ matches before every line terminator and at the very end. You enable it either with the Pattern.MULTILINE flag passed to Pattern.compile, or inline with the embedded flag (?m) at the start of the pattern. MULTILINE only affects the line anchors ^ and $; it does not change what . matches (that is DOTALL). It also does not affect the input anchors \A, \z, and \Z, which always refer to the whole input regardless of MULTILINE. A common use is scanning multi-line text line by line, for example matching every line that starts with a given prefix.

code

java · 13 lines
java
import java.util.regex.*;

String text = "foo\nbar\nbaz";

Pattern def = Pattern.compile("^ba\\w+");           // default
System.out.println(def.matcher(text).find());       // false (start is 'foo')

Pattern ml = Pattern.compile("^ba\\w+", Pattern.MULTILINE);
Matcher m = ml.matcher(text);
while (m.find()) System.out.println(m.group());     // bar, baz

// inline flag form:
System.out.println(Pattern.compile("(?m)^bar$").matcher(text).find()); // true

go deeper

for a junior

Knows MULTILINE exists and makes ^ and $ work per line.

for a middle

Enables it via Pattern.MULTILINE or (?m), and distinguishes it from DOTALL.

for a senior

Explains the exact positions ^/$ fire at relative to line terminators and that input anchors are unaffected.

for a principal

Reasons about flag composition and choosing line vs input anchors deliberately in parsers/validators, anticipating multiline-injection edge cases.

## The default: single-line mode In Java, a `Pattern` is by default in **single-line mode** for the purposes of `^` and `$`. That means the whole input — even if it contains embedded newlines — is treated as one unit. `^` matches **only** at the very start; `$` matches **only** at the very end (with Java's tolerance for one trailing line terminator). 'Single-line' here is a confusing historical name: it does **not** mean `.` matches newlines; it means the **anchors** see only one line (the whole input). ## What a line terminator is A **line terminator** is a character (or pair) that marks the end of a line: `\n` (line feed), `\r` (carriage return), `\r\n`, plus a few Unicode ones (` `, `
`, `
`). These are the boundaries `^` and `$` care about in multiline mode. ## Turning on MULTILINE With **MULTILINE** enabled: - `^` matches at the **start of the input** AND **immediately after each line terminator**. - `$` matches **before each line terminator** AND at the **end of the input**. So for the input `"foo\nbar"`, the pattern `^bar` does **not** match in default mode (bar isn't at input start) but **does** match in MULTILINE mode (bar starts a line). ## Two ways to enable it 1. **Flag argument:** `Pattern.compile("^bar$", Pattern.MULTILINE)`. 2. **Embedded flag:** put `(?m)` at the start of the pattern: `Pattern.compile("(?m)^bar$")`. You can scope it to part of a pattern with `(?m:...)`. Flags combine with `|`: `Pattern.compile(pat, Pattern.MULTILINE | Pattern.CASE_INSENSITIVE)`. ## What MULTILINE does NOT do - It does **not** change `.`. By default `.` matches any character **except** line terminators; to make `.` also match newlines you need the **separate** `DOTALL` flag (`(?s)`). Mixing these two up is the single most common regex bug in this area. - It does **not** affect the **input anchors** `\A` (input start), `\z` (input end), and `\Z` (end before a final terminator). Those always refer to the whole input, which is exactly why you use them when you want guaranteed whole-input anchoring even in MULTILINE mode. ## Practical use MULTILINE shines when you process a block of text line by line in one pass — e.g. find every line beginning with `#`, or validate that every line matches a format — without splitting the string first.

  • If you need ^ to behave per-line but still want to assert the true end of input, what do you use?
    Combine MULTILINE ^ with the input anchor \z (or \Z): MULTILINE gives per-line ^, while \z/\Z still pins the absolute end of input regardless of the flag.
  • Which flag makes . match newline characters?
    DOTALL (Pattern.DOTALL, inline (?s)). MULTILINE does not affect ., only the ^ and $ anchors.

saying these in an interview costs you the question

  • Confusing MULTILINE with DOTALL (DOTALL changes ., MULTILINE changes ^/$)
  • Thinking 'single-line' default means . matches newlines
  • Believing MULTILINE changes \A/\z/\Z (it does not)
  • Assuming you must split the string by lines before matching

context