RegExp.prototype.unicode
Returns whether the regular expression was created with the u flag.
get RegExp.prototype.unicode- Added in JavaScript ES2015 (ES6)
Return value
booleantrue if the u flag is set, false otherwise. It is false for a regex using the v flag; check unicodeSets for that.
Errors
TypeError if accessed on a value that is not a RegExp object (other than RegExp.prototype itself). Constructing a regex with both u and v throws a SyntaxError.
Changelog
- PHP ES2018Unicode property escapes \p{...} and \P{...} were added, and require u (or v) to be recognised as escapes.
- PHP ES2024The v (unicodeSets) flag arrived as a stricter alternative with set notation in character classes; u and v cannot be combined and the unicode property stays false under v.
unicode reports whether the u flag is set. That flag switches the engine from UTF-16 code units to Unicode code points and turns on four things worth having.
What u enables
- Property escapes.
\p{Letter},\p{Script=Greek},\p{Emoji}only work withuorv. - Whole characters.
.and character classes treat a surrogate pair as one unit, so/^.$/u.test("😄")istrue. - Code-point escapes.
\u{1F604}is a code point rather than a repeatedu. - Strict syntax. Meaningless escapes throw instead of being quietly reinterpreted.
The silent failure
Without u, \p{L} is a legacy identity escape — it does not throw, it matches the literal text p{L}. Nothing warns you; the pattern just never matches real input. If you write a property escape, the flag is not optional.
u also makes lastIndex advance by code points, so a global scan will not split an emoji in half. Note that combining characters and ZWJ sequences are still multiple code points — use Intl.Segmenter for user-perceived characters.
Example
When to use it
- Match letters in any script rather than just a-z
- Count or split emoji without splitting surrogate pairs
- Validate that a name field contains only letters and marks
Frequently asked questions
Why does \p{L} not work in my regex?
The u (or v) flag is missing. Without it \p{L} is a legacy identity escape that matches the literal characters "p{L}" instead of any letter, and no error is raised. Write /\p{L}/u.
How do I match emoji without breaking surrogate pairs?
Add the u flag so the engine works in code points: /./gu treats an emoji as one match. For emoji built from several code points, such as ZWJ sequences and flags, use \p{RGI_Emoji} with the v flag or Intl.Segmenter.
Should I use the u flag or the v flag?
Use u unless you need set notation — intersection, subtraction and string properties — inside character classes, which is what v adds. They cannot be combined, and the unicode property reports false under v; check unicodeSets instead.
More examples
Iteration advances by code point
With u the engine steps a whole code point at a time, so an emoji is replaced once rather than twice and a lone surrogate no longer matches a class containing the full character. This is the flag that keeps string surgery from producing mojibake.
console.log("😄a".replace(/./gu, "_")); // "__"
console.log("😄a".replace(/./g, "_")); // "___" - split the pair
console.log([..."a😄b".matchAll(/./gu)].map(m => m[0]));
console.log(/[😄]/u.test("\ud83d")); // false
console.log(/[😄]/.test("\ud83d")); // true - lone surrogateProperty escapes for real-world validation
\p{L} plus \p{M} covers letters and their combining marks in every script, which is what a name field actually needs. Note that \d stays strictly 0-9 even under u — \p{Nd} is the Unicode-aware equivalent.
const name = /^[\p{L}\p{M}'\- ]+$/u;
console.log(name.test("Zoë O'Néill-Smith")); // true
console.log(name.test("user123")); // false
console.log(/\p{Nd}/u.test("٣")); // true - Arabic-Indic digit
console.log(/\d/u.test("٣")); // false - \d is ASCII only
console.log("héllo!".match(/[\p{L}\p{M}]+/gu));
Discussion