Script Valley
Regex: Actually Useful Patterns
Regex FundamentalsLesson 1.5

Regex flags global case-insensitive multiline explained

g flag, i flag, m flag, s flag, flag combinations, findAll behavior, flag syntax JS vs Python

Flags Change How the Engine Behaves

Regex flags

Flags are appended after the closing delimiter in JavaScript (/pattern/flags) or passed as a string argument in Python (re.findall(pattern, string, re.I)). They modify engine behavior globally for that pattern.

The Four You'll Actually Use

  • i โ€” case-insensitive: a matches A
  • g โ€” global: find all matches, not just the first
  • m โ€” multiline: ^/$ match line boundaries
  • s โ€” dotAll: dot matches newlines too
// JavaScript
'Hello WORLD'.match(/hello/i)       // ['Hello']
'aabbcc'.match(/[a-z]/g)            // ['a','a','b','b','c','c']
'line1\nline2'.match(/^line\d/gm)  // ['line1', 'line2']

# Python
re.findall(r'hello', 'Hello WORLD', re.I)  # ['Hello']
re.findall(r'[a-z]', 'aabbcc')            # ['a','a','b','b','c','c']
re.findall(r'^line\d', 'line1\nline2', re.M) # ['line1', 'line2']

Combine Flags

/pattern/gi        // global + case-insensitive
re.findall(r'pat', s, re.I | re.M)  // Python combines with |

Without g, match() returns only the first result even if multiple exist. This is a common source of bugs โ€” always ask whether you want one match or all matches before choosing your method.

A subtle bug with the g flag: when you use regex.test(str) in a loop with a globally-flagged regex stored in a variable, the engine updates lastIndex after each call and starts from there next time. This causes alternating true/false results on repeated calls. The fix: either use a fresh regex literal each time, reset regex.lastIndex = 0 before testing, or use str.match(regex) which handles this correctly. This is one of the most common regex bugs in production JavaScript code.

Regex flags global case-insensitive multiline explained โ€” Regex Fundamentals โ€” Regex: Actually Useful Patterns โ€” Script Valley โ€” Script Valley