skip to content

Pattern Flags

The compile flags and their inline equivalents: CASE_INSENSITIVE, MULTILINE, DOTALL, UNICODE_CASE and COMMENTS, with scoped inline forms. DOTALL versus MULTILINE is the confusion interviewers like to clear up.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

5

How do you make a Java regex match case-insensitively, and what is the difference between the CASE_INSENSITIVE flag and the (?i) inline flag?

level: juniorimportance: must knowfreq 70%

answer

  1. CASE_INSENSITIVE int constant vs (?i) inline — same bit
  2. Inline flag = switch lives in the pattern string
  3. ASCII-only unless you add UNICODE_CASE / (?u)
  4. Scope with (?i:...), turn off with (?-i:...)

basics

~10 s

Pass Pattern.CASE_INSENSITIVE when compiling the pattern, or put (?i) at the start of the pattern string. Both make letters match regardless of upper or lower case, so "abc" matches "ABC".

solid answer

~40 s

There are two equivalent ways to ask for case-insensitive matching. The compile-time way: Pattern.compile("abc", Pattern.CASE_INSENSITIVE). The inline way: embed (?i) inside the pattern itself, e.g. Pattern.compile("(?i)abc"). Both set the same internal flag, so the result is identical. The practical differences are about location and scope: a compile flag applies to the whole pattern and lives in your Java code; an inline (?i) lives in the pattern string itself, which is handy when the pattern comes from config or a file where you can't pass Java flags. Inline flags can also be scoped to part of the pattern with (?i:...). One gotcha: by default CASE_INSENSITIVE only folds ASCII letters (A-Z); to fold accented and other Unicode letters you must additionally enable UNICODE_CASE (or (?u)).

code

java · 18 lines
java
import java.util.regex.Pattern;

// Compile-time flag
Pattern a = Pattern.compile("hello", Pattern.CASE_INSENSITIVE);
System.out.println(a.matcher("HELLO").matches()); // true

// Inline flag (same effect)
Pattern b = Pattern.compile("(?i)hello");
System.out.println(b.matcher("HeLLo").matches()); // true

// Scoped: only 'foo' is case-insensitive
Pattern c = Pattern.compile("(?i:foo)BAR");
System.out.println(c.matcher("FOOBAR").matches()); // true
System.out.println(c.matcher("FOObar").matches()); // false (BAR is case-sensitive)

// Unicode letters need UNICODE_CASE
Pattern d = Pattern.compile("é", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
System.out.println(d.matcher("É").matches()); // true (é matches É)

go deeper

for a junior

Knows both mechanisms exist and that (?i) goes at the front of the pattern; can call Pattern.compile with CASE_INSENSITIVE.

for a middle

Explains they set the same internal flag and chooses inline when the pattern comes from external config; knows about (?i:...) scoping.

for a senior

Articulates the ASCII-only default and the need for UNICODE_CASE/(?u) for Unicode letters; explains turning flags off with (?-i:...).

for a principal

Discusses full vs simple case folding limits (ß, locale-sensitive casing), performance/clarity trade-offs of compile flags vs inline, and policy for patterns sourced from untrusted input.

## What a regex flag is A **regular expression** (regex) is a small pattern language for describing text. In Java the pattern is compiled into a `java.util.regex.Pattern` object, which you then use to build a `Matcher` that scans some input. A **flag** is an on/off switch that changes *how* the whole pattern is interpreted. Without flags, matching is exact: the letter `a` matches only the lowercase `a`. ## The two ways to set a flag 1. **Compile-time flag (a Java `int` constant):** `Pattern.compile(regex, Pattern.CASE_INSENSITIVE)`. `CASE_INSENSITIVE` is a public `static final int` on `Pattern` (its value is `0x02`, but you should never hardcode the number — use the constant). You can OR several flags together with `|`. 2. **Inline (embedded) flag:** a token written *inside the pattern string* using the syntax `(?flags)`. For case-insensitivity the letter is `i`, so `(?i)`. Placed at the very start, `(?i)abc` behaves exactly like compiling `abc` with `CASE_INSENSITIVE`. They are not just similar — they flip the **same** internal bit, so the matching behavior is identical. The choice is about *where the switch lives*: - A compile flag lives in your Java source and applies to the entire pattern. - An inline flag lives in the pattern *text*. This matters when the pattern is supplied by something that can't pass Java flags — a config file, a database row, user input, or an annotation that only takes a string. You put the switch in the string itself. ## Scoping A leading `(?i)` turns the flag on for the rest of the pattern. You can instead scope it to a sub-pattern with a **non-capturing group that carries the flag**: `(?i:abc)def` makes only `abc` case-insensitive while `def` stays case-sensitive. You can also turn a flag *off* inside a region with `(?-i:...)`. ## The Unicode caveat By default `CASE_INSENSITIVE` (and `(?i)`) only fold the basic ASCII letters `A`–`Z`. So with only this flag, the pattern `é` would NOT match `É`. To fold case across the full Unicode range you must *also* enable `UNICODE_CASE` (constant `Pattern.UNICODE_CASE`, inline `(?u)`). A common correct combination is `Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE`, or the inline `(?iu)`. ## How to derive the answer If asked "make this match ignore case," reach for either `Pattern.CASE_INSENSITIVE` (when you control the Java call) or `(?i)` at the front of the pattern (when you only control the string). If non-ASCII letters are in play, add `UNICODE_CASE`/`(?u)`.

  • Your pattern comes from a properties file and you cannot change the Java call. How do you make it case-insensitive?
    Prepend (?i) to the pattern string in the file (or wrap the relevant part in (?i:...)), since you can't pass Pattern.CASE_INSENSITIVE from code.
  • Why might a case-insensitive match still fail to match 'STRASSE' against 'straße'?
    Default case folding is ASCII-only; you need UNICODE_CASE, and even then ß↔SS is a special full-case-folding rule the simple flag may not cover.

saying these in an interview costs you the question

  • Thinking (?i) and CASE_INSENSITIVE do different matching — they set the same flag
  • Assuming case-insensitive matching folds accented/Unicode letters by default (it does not without UNICODE_CASE)
  • Hardcoding the numeric flag value instead of the named constant
  • Using (?i) in the middle of a pattern and expecting it to retroactively affect text before it

context

open as a page

Explain the difference between Pattern.MULTILINE (?m) and Pattern.DOTALL (?s) in Java regex. Which anchors/metacharacters does each affect?

level: middleimportance: must knowfreq 65%

basics

~20 s

MULTILINE makes ^ and $ match at the start and end of every line, not just the whole input. DOTALL makes the dot '.' match newline characters too. They control different things and are often confused.

open as a page

How do you combine multiple Pattern flags in Java, and how does combining compile-time flags compare to combining inline flags? Give the bitwise mechanism.

level: middleimportance: should knowfreq 35%

basics

~10 s

Combine compile-time flags with the bitwise OR operator |, e.g. Pattern.CASE_INSENSITIVE | Pattern.MULTILINE. Inline, just list the letters together, e.g. (?im). Both ways enable several flags at once.

open as a page

What does Pattern.COMMENTS / (?x) do, and what are the rules and pitfalls when using it to write a readable regex?

level: middleimportance: should knowfreq 30%

basics

~20 s

COMMENTS (inline (?x)) lets you spread a regex over multiple lines: it ignores unescaped whitespace and treats # as a comment to end of line. To match a real space you must escape it (\ ) or use \s.

open as a page

How do inline flag groups like (?i:...) work in Java regex, and how do they differ from a leading (?i)? How do you turn a flag off for part of a pattern?

level: seniorimportance: should knowfreq 40%

basics

~20 s

A leading (?i) turns a flag on for the rest of the pattern. The form (?i:...) is a non-capturing group that applies the flag only inside that group. You turn a flag off for a region with (?-i:...).

open as a page