DevLab
.*
Regexbeginner

Regex Flags Explained

understand what regex flags g, i, m, s, u, y do with live examples

By Bikram NathLast updated

Regex flags change how a pattern matches without altering the pattern itself. The global flag (`g`) makes `/cat/g` find every occurrence in a string instead of stopping after the first; without it, `'catcat'.match(/cat/)` returns only one result. The `s` (dotAll) flag is the one most developers forget exists — it makes `.` match newline characters, which it silently skips by default.

Try it now — free, instant, no signup

What is Regex Flags Explained?

Regex Flags Explained is an interactive reference that runs each ECMAScript flag in isolation and in combination, showing you live how the same pattern behaves differently with and without each modifier. Paste a pattern and a test string, toggle flags one at a time, and the match output updates immediately so you can see, for example, that adding `i` to `/hello/` makes it match 'Hello', 'HELLO', and 'hElLo' without touching the pattern.

Developers typically reach for regex101 when they need a full-featured debugger with a match-step visualizer and regex flavor switching (PCRE, Python, Java). This tool is narrower: it focuses exclusively on JavaScript's six flags and is useful when you already know your pattern works but you're unsure which combination of flags to ship with it, or when you want to teach a colleague what `m` actually does to `^` and `$`.

The most common confusion with flags involves `m` versus `s`. The multiline flag (`m`) does not make `.` span lines — it only changes where `^` and `$` anchor. To make `.` cross a newline you need `s`, which was added in ECMAScript 2018 and is unavailable in Node.js below v10. The `y` (sticky) flag is subtler still: it respects `lastIndex` and will fail a match rather than scanning forward, which makes it useful for tokenizers but confusing in one-off scripts.

When to use Regex Flags Explained

Debug a regex that stops matching after the first hit by confirming whether the `g` flag is missing.
Verify that your multiline pattern's `^` anchors are matching line starts rather than only the string start before deploying.
Audit a third-party regex you've inherited to understand which flags it expects before integrating it into a parser.

Frequently Asked Questions

Why does adding the `g` flag break my `exec()` loop?
When you use `RegExp.prototype.exec()` with the `g` flag, the regex object tracks position via its `lastIndex` property. Each successful call advances `lastIndex`; when no match is found, it resets to 0. If you create the regex inside a loop with a literal like `/foo/g`, JavaScript recreates the object each iteration and resets `lastIndex` to 0, causing an infinite loop. The fix is to declare the regex once outside the loop, or switch to `String.prototype.matchAll()` which manages iteration for you.
Does the `u` flag change which characters `\w` and `\d` match?
No, and that surprises many developers. The `u` flag enables full Unicode code-point mode and makes the engine reject malformed escape sequences (which are silently ignored without it), but `\w` still only matches `[A-Za-z0-9_]` and `\d` still only matches `[0-9]`. To match Unicode letters or digits you need a Unicode property escape like `\p{Letter}` or `\p{Decimal_Number}`, which also requires the `u` flag. So `u` is a prerequisite for `\p{}` but does not upgrade the classic shorthand classes.
Why does `/^line/m` match in the middle of my string?
With the `m` (multiline) flag active, `^` matches at the start of the string and immediately after each `\n` character. So for the input `'first\nsecond'`, the pattern `/^second/m` matches at position 6 because that position follows a newline. Without `m`, `^` only anchors to the very start of the entire string. This is the flag's entire effect; it has no impact on how `.` behaves, on `\b`, or on any other metacharacter.
When would I actually use the `y` (sticky) flag over `g`?
The sticky flag is designed for hand-written tokenizers and parsers. Unlike `g`, which scans forward through the string to find the next match anywhere, `y` only matches at exactly `lastIndex` and fails immediately if there is no match at that position. This means you can process a string token by token in sequence, and any gap in coverage produces an explicit failure rather than silently skipping characters. Parser libraries like Moo and some hand-rolled JSON scanners use `y` precisely because that fail-fast behavior surfaces malformed input early.
Is the `s` (dotAll) flag safe to use in all browsers today?
Yes for all modern targets. The `s` flag shipped in ECMAScript 2018 and has been supported in Chrome 62, Firefox 78, Safari 11.1, and Node.js 10 onward. The only realistic environments where it is missing are Internet Explorer (all versions), legacy Android WebViews below version 62, and Node.js 8 LTS which reached end-of-life in December 2019. If your codebase still targets any of these, the workaround is replacing `.` with `[\s\S]` or `[\d\D]` in the pattern.

Related Tools