(?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)aonAmatches in seven engines. JavaScript is-: no inline flags. Its flags go in the second argument, and thenode=option on other pages' rows is how the driver passes them. - Row 2, a mid-pattern
(?i).a(?i)bonaBmatches 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)bonABfails everywhere it compiles:bwas made case-sensitive again. - Rows 4–5,
sandm.(?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+onaatakes onea. Java:UNICODE_CHARACTER_CLASS, anda+takes both. Same letter, unrelated features. - Rows 8–9,
(?a)and(?u). Python, Perl and Ruby havea; oné,(?a)\wmatches nothing — ASCII rules. Java, Go and Rust refuse the letter.(?u)\wmatcheséin Python, Perl, Ruby and Rust; in Java(?u)isUNICODE_CASEand\wstays ASCII, sono. Go refuses both. - Row 10,
(?d). Perl (default rules), Ruby and Java (UNIX_LINES) accept it; each answersnofor 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¶
- Flags, and where you can turn one on — every flag per engine, the CRLF rows, the scoping of a mid-pattern
(?i), and the ABAPIGNORING CASEalternative.
See also¶
- Non-capturing group —
(?i:…), the scoped form. .·^·$— whatsandmchange.- Comment — what
xenables.