The i flag: case insensitive matching
The i flag makes literal characters and character ranges match in either case. It changes nothing about the meaning of \d, \w or \s, and it never makes a pattern accent insensitive.
At a glance
- Flag letter
- i
- Property
- RegExp.prototype.ignoreCase
- Affects
- literal characters, character sets, ranges and backreferences
- Leaves alone
- \d, \w and \s, whose definitions have no notion of case
- Accents
- no, /cafe/i still does not match café
- With the u flag
- folding widens slightly, so /K/ui also matches the Kelvin sign U+212A
In detail
The flag folds case on both sides of the comparison, which quietly changes what a range means. Matching /[A-Z]+/ against "Hello World" gives the two capitals, H and W. Add i and the same pattern gives Hello and World, because every lowercase letter now falls inside the range. If you actually wanted uppercase only, i is the wrong tool and the pattern should not have it.
Negation happens after folding, which trips people writing exclusion rules. /[^a]/i does not match a capital A, because A folds to a and a is excluded. A pattern meant to reject one letter in one case cannot be written with the i flag on at all.
What the flag does not touch is a longer list than what it does. It performs no accent folding, no Unicode normalisation and no width folding. Comparing café with CAFÉ needs toLowerCase or localeCompare, and \w still rejects é whether i is set or not, so /^\w+$/i keeps failing on names with diacritics.
Turning on u as well brings in simple case folding, which adds a small number of non-ASCII equivalences. /K/ui matches U+212A KELVIN SIGN and /s/ui matches U+017F LATIN SMALL LETTER LONG S. Harmless in ordinary prose, and a real hole if the pattern is being used as a denylist.
Examples
"Hello World".match(/[A-Z]+/g); // ["H", "W"]
"Hello World".match(/[A-Z]+/gi); // ["Hello", "World"]
/[^a]/i.test("A"); // false, negation applies after folding
/cafe/i.test("café"); // false, i folds case and nothing else/K/i.test("\u212A"); // false (Kelvin sign)
/K/ui.test("\u212A"); // true
/s/ui.test("\u017F"); // true (long s)Two characters that look like ordinary letters start matching once u and i are both on.
Things that catch people out
- Writing /[a-zA-Z]/i is merely redundant. Writing /[A-Z]/i when you meant uppercase only is a silent bug, because the flag widened the range without touching the source.
- The i flag does not fold accents, so a case insensitive search still misses résumé when the user typed resume. Normalise the text before matching if that matters.
- A denylist compiled with u and i can be stepped around with U+212A or U+017F, and one compiled without u will not fold them at all. Either way a regex denylist is the weakest available check.
Try it: Regex Tester
Type a pattern and a test string, watch every match highlight as you go, read a plain English breakdown of each token, and check the numbered and named groups it captured.
Regex Tester
LOCAL · Browser-OnlyTest and debug regular expressions with live matching and highlights
Related Regex syntax
All regex syntax →The u flag: Unicode mode
What the u flag changes about how a pattern is parsed, the escape forms it unlocks, and the previously tolerated syntax it turns into a hard error.
[a-z] ranges: code point order and the A-z bug
Ranges inside a character class run by code point, which is why [A-z] quietly includes six punctuation characters and [a-Z] is a syntax error.
The g flag: global matching and the lastIndex trap
What the g flag changes in a JavaScript regex, why a reused global pattern skips matches through lastIndex, and when matchAll is the safer choice.
The m flag: multiline anchors
What multiline mode changes about ^ and $, which line terminators JavaScript counts, and why the m flag never makes the dot match a newline.
The s flag: dotAll mode
What dotAll changes, why it has no effect at all on character classes, and the [\s\S] idiom that did the same job before the s flag existed.
The y flag: sticky matching at lastIndex
How the sticky flag anchors a match to the current lastIndex, why it is the right tool for a hand written tokenizer, and how it behaves alongside g.
Tools for this
- Regex Tester Free online regex tester - test and debug regular expressions with live matching and highlights
- Regex Playground Regex playground with live match highlighting, named groups, find and replace, and shareable links