Regular Expression Flags Reference

Every regex flag, what it actually does, the syntax in JavaScript / Python / Go, and the common mistakes engineers make with each one.

Quick reference

FlagNameEffect
g Global Match all occurrences in the string, not just the first one.
i Case-Insensitive Match letters regardless of upper/lower case.
m Multiline Makes ^ and $ match the start and end of each line, not just the whole string.
s DotAll (single line) Makes . match newline characters too, not just non-newline characters.
u Unicode Treats the pattern as a sequence of Unicode code points, not bytes. Enables \u{...} escapes and \p{...} property matches.
y Sticky Matches only at the lastIndex position of the regex; does not scan forward.
d hasIndices Include match start/end indices for the full match and each capture group in the result.
x Extended / Verbose Allow whitespace and # comments inside the pattern for readability. Not available in JavaScript.

g — Global

Match all occurrences in the string, not just the first one.

Syntax across languages

JS: /pattern/g · Python: re.findall (implicit) · Go: regexp.FindAllString

Example

// JavaScript
"a-b-c".replace(/-/g, "_")   // "a_b_c"  (all dashes)
"a-b-c".replace(/-/, "_")    // "a_b-c"  (first only, no /g)

Common gotcha

In JavaScript, /g changes the behaviour of String.match() — without /g it returns capture groups; with /g it returns an array of full matches and no groups.

i — Case-Insensitive

Match letters regardless of upper/lower case.

Syntax across languages

JS: /pattern/i · Python: re.IGNORECASE / re.I · Go: (?i)pattern

Example

// JavaScript
"Hello".match(/hello/i)    // ["Hello"]
"Hello".match(/hello/)     // null

Common gotcha

Unicode letters: in JavaScript, /i alone is byte-level. Combine with /u for proper case folding on accented and non-Latin characters.

m — Multiline

Makes ^ and $ match the start and end of each line, not just the whole string.

Syntax across languages

JS: /pattern/m · Python: re.MULTILINE / re.M · Go: (?m)pattern

Example

// JavaScript
"a\nb\nc".match(/^./gm)   // ["a", "b", "c"]
"a\nb\nc".match(/^./g)    // ["a"]  (without /m)

Common gotcha

/m does NOT make . match newlines. For that you need /s (dotAll). The two are commonly confused.

s — DotAll (single line)

Makes . match newline characters too, not just non-newline characters.

Syntax across languages

JS: /pattern/s (ES2018+) · Python: re.DOTALL / re.S · Go: (?s)pattern

Example

// JavaScript
"a\nb".match(/a.b/s)    // ["a\nb"]
"a\nb".match(/a.b/)     // null

Common gotcha

The name is misleading — "single line" mode actually treats the input as a single line so that . can cross line boundaries.

u — Unicode

Treats the pattern as a sequence of Unicode code points, not bytes. Enables \u{...} escapes and \p{...} property matches.

Syntax across languages

JS: /pattern/u · Python: re.UNICODE / re.U (default in Python 3) · Go: regexp is always UTF-8

Example

// JavaScript
"😀".match(/^.$/)    // null (without /u — emoji is two surrogate halves)
"😀".match(/^.$/u)   // ["😀"]
"café".match(/\p{Letter}+/u)   // ["café"]

Common gotcha

Without /u, JavaScript treats characters above U+FFFF as two separate surrogate code units — your pattern may match in the wrong place.

y — Sticky

Matches only at the lastIndex position of the regex; does not scan forward.

Syntax across languages

JS only: /pattern/y

Example

// JavaScript
const re = /foo/y;
re.lastIndex = 4;
re.test("xxxxfoo")    // true — matches starting at index 4
re.lastIndex = 3;
re.test("xxxxfoo")    // false — does NOT scan to position 4

Common gotcha

Mostly useful for tokenisers / lexers that need anchored matching at a specific cursor position.

d — hasIndices

Include match start/end indices for the full match and each capture group in the result.

Syntax across languages

JS only (ES2022+): /pattern/d

Example

// JavaScript
const m = "hello".match(/l(l)/d);
m.indices        // [[2, 4], [3, 4]]
// [start, end] of full match, then each group

Common gotcha

New in ES2022 — older browsers ignore the flag. Useful for syntax highlighters, linters, and editor integrations.

x — Extended / Verbose

Allow whitespace and # comments inside the pattern for readability. Not available in JavaScript.

Syntax across languages

Python: re.VERBOSE / re.X · Perl, PCRE, Ruby: (?x)

Example

# Python
import re
pattern = re.compile(r"""
  ^               # start
  (?P<area>\d{3}) # area code
  -
  (?P<num>\d{4})  # number
  $               # end
""", re.X)
pattern.match("555-1234").groupdict()
# {'area': '555', 'num': '1234'}

Common gotcha

JavaScript does not support /x. To get readable patterns in JS, build them programmatically with new RegExp() from concatenated strings.

English phrases engineers use

  • "Add /g to match all occurrences — without it you only replace the first one."
  • "This regex is case-sensitive — add the i flag."
  • "In multiline mode, ^ matches the start of each line."
  • "By default, the dot does not match newlines — you need s (dotAll) for that."
  • "Without u, emoji break the regex because they are surrogate pairs."
  • "This regex is too greedy; let's use a non-greedy quantifier."