Regex Flags Explained
A practical guide to regular expression flags, including global, case-insensitive, multiline, dotAll, Unicode, sticky, and indices modes with JavaScript examples.
Regex flags are optional settings that change how a regular expression behaves. They can control whether matching is case-sensitive, whether a pattern searches through the entire string, how anchors treat line breaks, whether the dot matches newline characters, and how Unicode text is interpreted.
Flags are especially important in JavaScript, where they are written after the closing slash of a regular expression literal. For example, /hello/i uses the i flag to make the match case-insensitive, while /hello/g searches for multiple matches instead of stopping after the first one.
Understanding flags is essential because the same regex pattern can produce very different results depending on which flags are enabled.
Regex Flags Quick Reference
| Flag | Name | Main purpose |
|---|---|---|
| g | Global | Find all matches instead of stopping after the first |
| i | Case-insensitive | Ignore letter case when matching |
| m | Multiline | Make ^ and $ work with individual lines |
| s | DotAll | Allow . to match line terminators |
| u | Unicode | Enable Unicode-aware regex behavior |
| y | Sticky | Require each match to start at lastIndex |
| d | Indices | Expose start and end positions of matches |
The exact set of available flags depends on the regex engine. The flags in this article focus primarily on modern JavaScript regular expressions.
How Regex Flags Are Written
In a JavaScript regex literal, flags are placed immediately after the closing slash.
/hello/i
/hello/g
/hello/gi
/^hello$/mMultiple flags can be combined. For example, gi means global and case-insensitive matching.
const pattern = /hello/gi;
console.log("Hello hello HELLO".match(pattern));
// ["Hello", "hello", "HELLO"]The Global Flag: g
The g flag stands for global matching. Without it, many JavaScript regex operations return only the first match. With g, the regex searches for multiple matches throughout the input.
const text = "cat cat cat";
console.log(text.match(/cat/));
// ["cat"]
console.log(text.match(/cat/g));
// ["cat", "cat", "cat"]The g flag is useful when you need every occurrence rather than the first occurrence.
- Finding every occurrence of a word.
- Extracting all numbers from a string.
- Replacing every occurrence with String.prototype.replace().
- Counting matches.
- Processing repeated values in a document.
Global Replacement
One of the most common uses of g is global replacement.
const text = "red red red";
const result = text.replace(/red/g, "blue");
console.log(result);
// "blue blue blue"Without g, replace() would replace only the first matching occurrence when using a string pattern in this way.
The Case-Insensitive Flag: i
The i flag makes matching case-insensitive for characters affected by the regex engine's case-folding rules.
const pattern = /javascript/i;
console.log(pattern.test("JavaScript"));
// true
console.log(pattern.test("JAVASCRIPT"));
// trueWithout i, the same pattern would normally distinguish uppercase and lowercase letters.
/javascript/.test("JavaScript");
// falseCombining i and g
The i and g flags are frequently combined when you want every occurrence regardless of capitalization.
const text = "JS js Js jS";
const matches = text.match(/js/gi);
console.log(matches);
// ["JS", "js", "Js", "jS"]The Multiline Flag: m
The m flag changes the behavior of the ^ and $ anchors. Without m, ^ normally refers to the beginning of the entire input and $ normally refers to the end of the entire input.
With m, these anchors can also match the beginning and end of individual lines.
const text = "first\nsecond\nthird";
console.log(text.match(/^second$/));
// null
console.log(text.match(/^second$/m));
// ["second"]The m flag does not make the dot match newlines. That is the job of the s flag. This distinction is important because m changes anchors, not the behavior of .
Using m to Find Lines
Multiline mode is useful when processing text containing multiple lines and you need to identify lines that begin or end with a particular pattern.
const text = "TODO: fix bug\nDone: deploy\nTODO: add tests";
const matches = text.match(/^TODO:.*$/gm);
console.log(matches);
// ["TODO: fix bug", "TODO: add tests"]Here m makes ^ and $ operate at line boundaries, while g finds every matching line.
The DotAll Flag: s
The s flag enables dotAll behavior. It allows the . character to match line terminators as well as ordinary characters.
const text = "hello\nworld";
console.log(/hello.world/.test(text));
// false
console.log(/hello.world/s.test(text));
// trueThis is useful when a pattern needs to match text that can span multiple lines.
s vs m
| Flag | Changes | Does not change |
|---|---|---|
| s | What . can match | Behavior of ^ and $ |
| m | Behavior of ^ and $ | What . can match |
These flags are often confused because both can appear in multiline text processing. Remember: s affects the dot, while m affects anchors.
The Unicode Flag: u
The u flag enables Unicode-aware behavior for JavaScript regular expressions. It changes how the regex engine interprets Unicode code points and enables certain Unicode-related syntax.
const pattern = /\u{1F600}/u;
console.log(pattern.test("😀"));
// trueThe u flag is particularly important when working with modern Unicode text, especially when patterns use Unicode code point escapes or Unicode property escapes.
Unicode Property Escapes and u
With Unicode-aware regex syntax, property escapes can be used to match characters by Unicode properties rather than by manually listing characters.
const pattern = /\p{L}+/gu;
console.log("Hello Привет 世界".match(pattern));
// ["Hello", "Привет", "世界"]Here \p{L} represents Unicode letters, while u enables the Unicode-aware interpretation. The g flag returns all matching sequences.
The Sticky Flag: y
The y flag enables sticky matching. A sticky regex must match at the position specified by its lastIndex property.
const pattern = /\d+/y;
pattern.lastIndex = 0;
console.log(pattern.exec("123 abc"));
// ["123"]
console.log(pattern.lastIndex);
// 3After the first successful match, lastIndex points to the end of that match. A subsequent exec() attempts to match exactly at that position.
const pattern = /\d+/y;
pattern.lastIndex = 0;
pattern.exec("123 abc");
console.log(pattern.exec("123 abc"));
// nullThe second attempt starts at index 3, where the input contains a space rather than digits. Unlike a normal global search, the sticky regex does not scan forward looking for the next possible match.
g vs y
| Flag | Matching behavior |
|---|---|
| g | Search forward for the next match |
| y | Match only at the current lastIndex position |
The sticky flag is useful for tokenizers and parsers where input must be consumed sequentially from a known position.
The Indices Flag: d
The d flag enables match indices. When used with methods such as exec(), the resulting match object contains an indices property describing the start and end positions of the matches.
const pattern = /cat/d;
const result = pattern.exec("A cat is here");
console.log(result.indices);
// [[2, 5]]The range [2, 5] means the match starts at index 2 and ends before index 5.
Indices are useful when an application needs exact source positions rather than only the matched text.
Indices with Capturing Groups
The d flag is especially useful when a regex contains capturing groups because the indices object can expose the ranges of those captures.
const pattern = /(cat) (dog)/d;
const result = pattern.exec("cat dog");
console.log(result.indices);
// [[0, 7], [0, 3], [4, 7]]The first range represents the complete match, while the following ranges correspond to the capturing groups.
The HasIndices Flag in JavaScript
JavaScript exposes information about regex flags through properties such as global, ignoreCase, multiline, dotAll, unicode, sticky, and hasIndices.
const pattern = /hello/gim;
console.log(pattern.global);
// true
console.log(pattern.ignoreCase);
// true
console.log(pattern.multiline);
// trueThese properties can be useful when code needs to inspect a regular expression that was created elsewhere.
The flags Property
JavaScript regex objects also expose a flags property containing the active flags as a string.
const pattern = /hello/gim;
console.log(pattern.flags);
// "gim"The returned string is useful when logging, debugging, or reconstructing regex configuration.
Combining Regex Flags
Flags can be combined when several behavior changes are needed.
| Pattern | Meaning |
|---|---|
| /hello/g | Find all hello matches |
| /hello/gi | Find all hello matches regardless of case |
| /^todo:/gim | Find TODO lines regardless of case |
| /.+/gs | Allow . to span line breaks and find matches globally |
| /\p{L}+/gu | Find Unicode letter sequences globally |
| /\d+/gy | Find digit sequences only at successive lastIndex positions |
| /(\w+)/d | Expose match and capture indices |
There is no requirement to use flags simply because they exist. Add only the flags required by the matching behavior you need.
Common Flag Combinations
gi: Global and Case-Insensitive
The gi combination is one of the most common regex configurations.
const text = "Error ERROR error warning";
const matches = text.match(/error/gi);
console.log(matches);
// ["Error", "ERROR", "error"]gm: Global and Multiline
The gm combination is useful when searching for multiple lines that satisfy a pattern.
const text = "TODO: fix\nDone: test\nTODO: deploy";
const matches = text.match(/^TODO:.*$/gm);
console.log(matches);
// ["TODO: fix", "TODO: deploy"]gs: Global and DotAll
The gs combination is useful when finding multiple matches where each match may span line breaks.
const text = "<p>One\nTwo</p><p>Three</p>";
const matches = text.match(/<p>.*?<\/p>/gs);
console.log(matches);
// ["<p>One\nTwo</p>", "<p>Three</p>"]For complex HTML parsing, however, a dedicated HTML parser is generally more appropriate than relying on regex.
gu: Global and Unicode
The gu combination is common when processing Unicode text with property escapes.
const text = "Hello Привет 世界";
const words = text.match(/\p{L}+/gu);
console.log(words);
// ["Hello", "Привет", "世界"]guy: Global, Unicode, and Sticky
The guy combination can be useful in tokenizer-style code that processes Unicode text sequentially. The exact implementation depends on how lastIndex is managed.
Flag Order
In JavaScript, flags are represented as a string and the engine normalizes their exposed order. You should not rely on a particular hand-written order when comparing flag strings; use the regex object's flags property when you need the canonical representation.
Flags and String Methods
Different JavaScript string methods interact with regex flags in different ways. The g flag is particularly important for methods such as match() and replace(), while exec() and test() have additional state-related behavior when g or y is used.
| Method | Flag behavior to remember |
|---|---|
| match() | g returns all matches; without g, the result includes the first match and capture information |
| matchAll() | Requires a global regex and provides an iterator over matches and captures |
| replace() | g replaces all matching occurrences; without g, only the first occurrence is replaced |
| replaceAll() | Requires a global regex when a regex is supplied |
| test() | g and y can make the regex stateful through lastIndex |
| exec() | g and y can make repeated calls stateful through lastIndex |
The g Flag and lastIndex
A global regex is stateful when used with methods such as exec() and test(). JavaScript stores the position for the next search in lastIndex.
const pattern = /cat/g;
const text = "cat cat";
console.log(pattern.exec(text));
// ["cat"]
console.log(pattern.lastIndex);
// 3
console.log(pattern.exec(text));
// ["cat"]
console.log(pattern.lastIndex);
// 7This stateful behavior can surprise developers who reuse the same global regex object across multiple operations.
The y Flag and lastIndex
Sticky matching relies even more directly on lastIndex because the next match must begin exactly there.
const pattern = /\w+/y;
const text = "hello world";
pattern.lastIndex = 0;
console.log(pattern.exec(text)[0]);
// "hello"
pattern.lastIndex = 6;
console.log(pattern.exec(text)[0]);
// "world"Regex Flags and Anchors
The m flag changes how ^ and $ behave, but it does not turn them into generic line separators. They still represent positions at the beginning or end of the input or, with multiline mode, at the beginning or end of a line.
const text = "one\ntwo\nthree";
console.log(text.match(/^\w+$/gm));
// ["one", "two", "three"]This is a common pattern for processing individual lines.
Regex Flags and the Dot
The . metacharacter normally matches most characters except line terminators. Adding s changes that behavior so that . can also cross line breaks.
/start.*end/.test("start\nend");
// false
/start.*end/s.test("start\nend");
// trueThis is often cleaner than replacing . with a broad character class simply to include line breaks.
Regex Flags and Unicode
Unicode text can expose differences between what appears to be one visible character and how it is represented internally. The u flag makes regex behavior more Unicode-aware and is important for patterns that rely on Unicode code points and property escapes.
When working with international text, do not assume that ASCII-oriented expressions such as [A-Za-z] represent every letter users may enter. Unicode property escapes can provide a more appropriate solution when the regex engine supports them.
The v Flag
Modern JavaScript also defines the v flag, which enables enhanced Unicode-aware regular expression behavior and set operations. It is intended as a more capable Unicode mode for patterns that need features beyond traditional u-mode behavior.
const pattern = /[\p{Script=Greek}&&\p{Letter}]+/v;The v flag is an advanced feature and is not required for ordinary regex tasks. Before using it, verify that the JavaScript runtime or browser environment where the code will run supports it.
u vs v
| Flag | Purpose |
|---|---|
| u | Unicode-aware regex behavior and Unicode property escapes |
| v | Enhanced Unicode-aware behavior with additional character-set capabilities |
For most everyday Unicode regex patterns, u remains sufficient. The v flag is primarily relevant when advanced Unicode character-set operations are needed.
Common Regex Flag Mistakes
- Using g when only the first match is needed and then accidentally relying on lastIndex state.
- Thinking m makes the dot match newlines.
- Thinking s changes the behavior of ^ and $.
- Using i when case-sensitive matching is actually required.
- Forgetting u when using Unicode property escapes.
- Assuming y searches forward like g.
- Using lookbehind or advanced Unicode features without checking runtime compatibility.
- Adding many flags without testing how they interact.
- Assuming a regex engine outside JavaScript supports exactly the same flags.
g Does Not Mean 'Find Everything' in Every Context
The global flag changes regex matching behavior, but the exact result still depends on the JavaScript method being used. For example, match(), matchAll(), replace(), exec(), and test() expose different aspects of global matching.
This is why adding g should not be treated as a universal requirement whenever a regex might have multiple matches. Choose the flag based on the operation you actually need.
When to Use Each Flag
| Need | Flag |
|---|---|
| Find every occurrence | g |
| Ignore letter case | i |
| Match beginning/end of individual lines | m |
| Allow . to cross line breaks | s |
| Use Unicode-aware regex features | u |
| Match exactly at lastIndex | y |
| Get match position ranges | d |
| Use advanced Unicode set operations | v |
A Practical Flag Selection Workflow
- Start with the simplest regex pattern without flags.
- Add g if you need multiple matches or global replacement.
- Add i if uppercase and lowercase should be treated equivalently.
- Add m if ^ and $ need to work at line boundaries.
- Add s if . needs to match across line breaks.
- Add u when Unicode-aware matching or Unicode property escapes are required.
- Add y only when matching must start exactly at lastIndex.
- Add d when your application needs precise match ranges.
- Consider v only when advanced Unicode character-set features are actually needed.
- Test the final combination against representative input.
Testing Regex Flags
Flags can substantially change the behavior of an otherwise simple regex, so testing should include both expected matches and expected non-matches.
- Test uppercase and lowercase input when using i.
- Test multiple occurrences when using g.
- Test several lines when using m.
- Test strings containing newline characters when using s.
- Test non-ASCII text when using u or v.
- Test lastIndex behavior when using g or y with exec() and test().
- Test returned indices when using d.
- Test the actual browser or runtime version used by the application.
Regex Flags vs Regex Syntax
Flags and regex syntax solve different problems. Syntax such as character classes, quantifiers, groups, anchors, and lookarounds describes the structure of the pattern. Flags change the matching rules applied to that pattern.
| Category | Examples |
|---|---|
| Pattern syntax | [A-Z], \d+, (), ^, $, (?=...) |
| Flags | g, i, m, s, u, y, d, v |
A good regex usually starts with a clear pattern. Flags should then be added only when the required matching behavior cannot be expressed by the pattern alone.
Regex Flags in Other Engines
Regex flags are not completely standardized across every programming language and regex engine. JavaScript, Python, PCRE, .NET, Java, and other implementations use overlapping concepts but can expose them through different syntax and feature sets.
For example, JavaScript uses g for global matching, while another language may handle repeated matching through its regex API rather than an equivalent global flag. Similarly, Unicode and multiline behavior can have different names or semantics.
Frequently Asked Questions
What are regex flags?
Regex flags are optional settings that change how a regular expression matches text. In JavaScript, common flags include g, i, m, s, u, y, d, and v.
What does the g flag mean in regex?
The g flag enables global matching. It allows operations such as match() and replace() to work with multiple occurrences instead of stopping after the first match. With exec() and test(), global regexes also use lastIndex state.
What does the i flag do?
The i flag makes matching case-insensitive according to the regex engine's case-folding rules. For example, /hello/i can match Hello, HELLO, and hello.
What is the difference between m and s?
The m flag changes the behavior of ^ and $ so they can work at individual line boundaries. The s flag changes the behavior of . so that it can match line terminators.
What does the u flag do?
The u flag enables Unicode-aware regular expression behavior in JavaScript. It is important for Unicode code point escapes and Unicode property escapes.
What is the difference between g and y?
The g flag searches forward for the next match, while y requires the next match to begin exactly at the regex object's lastIndex position. Sticky matching is useful for sequential tokenization.
What does the d flag do?
The d flag enables match indices in JavaScript. Regex results can then expose the start and end positions of the complete match and capturing groups through the indices property.
Can regex flags be combined?
Yes. JavaScript allows multiple compatible flags to be combined, such as gi for global case-insensitive matching or gm for global multiline matching. The appropriate combination depends on the behavior required by the application.
Conclusion
Regex flags are an important part of writing predictable regular expressions. The g flag enables global matching, i ignores case, m changes anchor behavior for multiple lines, s allows the dot to match line terminators, u enables Unicode-aware behavior, y provides sticky matching, and d exposes match indices. Modern JavaScript also provides v for advanced Unicode-aware character-set operations.
The most important flags for everyday frontend development are usually g, i, m, s, and u. The y and d flags become useful for more specialized parsing, tokenization, and source-position tasks, while v is primarily relevant to advanced Unicode processing.
Rather than adding flags automatically, start with the behavior your application needs and choose only the flags that support it. Test combinations carefully, especially when using stateful g or y regexes, and always check compatibility when a pattern will run in different JavaScript environments or regex engines.