Skip to content

(?i), (?m), (?s), (?x), (?-i) — a flag that travels with the pattern

One line: An inline flag turns an option on from where it appears — case-insensitivity i, multiline anchors m, dot-matches-newline s, free-spacing x — in every engine here except JavaScript, which has no inline flags at ES2018; the letters beyond those four are engine-specific, and Ruby's m means everyone else's s.

Level: reference · one construct, eight engines

What it means

Flags can be passed beside the pattern (re.I, Pattern.CASE_INSENSITIVE, /i) or written inside it. The inside form has a real advantage: the pattern carries its own meaning when it is copied into a config file, a log line, a grep, or another language.

Letter Meaning Where it differs
i case-insensitive which table — see case-insensitive matching
m ^ and $ match at line boundaries Ruby: dot matches newline
s . matches newline Ruby: does not exist
x ignore whitespace and # comments Go: does not exist; Perl also has xx
U swap greedy and lazy Go, Rust; Java: Unicode character classes
a ASCII-only \w \d \s \b Python, Perl
u Unicode Python (default), Perl, Rust; Java: Unicode case folding only
d Perl: default charset rules; Java: UNIX_LINES —
R Rust: CRLF mode Perl/PCRE2: recursion, in a different syntax

Measured

Verified output of kw_inline_flags_sh.sh — regenerated by tools/run_examples.py, never hand-typed.

construct          python  perl    node  ruby    java  go    rust    fancy
(?i)               A       A       -     A       A     A     A       A
(?i) mid-pattern   -       aB      -     aB      aB    aB    aB      aB
(?i) then (?-i)    -       no      -     no      no    no    no      no
(?s)               a\nb    a\nb    -     -       a\nb  a\nb  a\nb    a\nb
(?m)               b       b       -     b       b     b     b       b
(?x) free-spacing  ab      ab      -     ab      ab    -     ab      ab
(?U) ungreedy      -       -       -     -       aa    a     a       a
(?a) ASCII         no      no      -     no      -     -     -       -
(?u)               \u{E9}  \u{E9}  -     \u{E9}  no    -     \u{E9}  \u{E9}
(?d) UNIX_LINES    -       no      -     no      no    -     -       -
unknown flag       -       -       -     -       -     -     -       -

Reading the table

  • Row 1. (?i)a on A matches in seven engines. JavaScript is -: no inline flags. Its flags go in the second argument, and the node= option on other pages' rows is how the driver passes them.
  • Row 2, a mid-pattern (?i). a(?i)b on aB matches in six engines: the flag applies from where it appears to the end of the enclosing group. Python refuses — since 3.11 a global inline flag must be at the very start, and a mid-pattern one is an error, which is the kinder failure than silently scoping it.
  • Row 3, turning a flag off. (?i)a(?-i)b on AB fails everywhere it compiles: b was made case-sensitive again.
  • Rows 4–5, s and m. (?s) is refused by Ruby. (?m) is accepted by everyone — and means the dot in Ruby and the anchors in the other six, which the dot page's table shows.
  • Row 6, (?x). Free-spacing exists in Python, Perl, Ruby, Java and Rust. Go refuses it.
  • Row 7, (?U). Go and Rust: ungreedy, a+ on aa takes one a. Java: UNICODE_CHARACTER_CLASS, and a+ takes both. Same letter, unrelated features.
  • Rows 8–9, (?a) and (?u). Python, Perl and Ruby have a; on é, (?a)\w matches nothing — ASCII rules. Java, Go and Rust refuse the letter. (?u)\w matches é in Python, Perl, Ruby and Rust; in Java (?u) is UNICODE_CASE and \w stays ASCII, so no. Go refuses both.
  • Row 10, (?d). Perl (default rules), Ruby and Java (UNIX_LINES) accept it; each answers no for its own reason. Row 11: an unknown flag letter is refused by all eight, which is the one row of universal agreement.

The trap

The letter collisions: m in Ruby, U and u in Java. A pattern that begins (?m) means something different in Ruby than in the engine it was copied from, and both compile. Prefer the four letters everybody shares — i, m (checking Ruby), s (avoiding Ruby), x (avoiding Go) — and put anything else in the host-language flags argument, where its name is spelled out.

Where it is measured in depth

See also