Unicode 字符类转义:\p{...}, \P{...}
Unicode 字符类别转义是一种字符类别转义,它匹配由 Unicode 属性指定的一组字符。它仅在Unicode 感知模式下受支持。当启用v 标志时,它也可以用于匹配有限长度的字符串。
试一试
const sentence = "A ticket to 大阪 costs ¥2000 👌.";
const regexpEmojiPresentation = /\p{Emoji_Presentation}/gu;
console.log(sentence.match(regexpEmojiPresentation));
// Expected output: Array ["👌"]
const regexpNonLatin = /\P{Script_Extensions=Latin}+/gu;
console.log(sentence.match(regexpNonLatin));
// Expected output: Array [" ", " ", " 大阪 ", " ¥2000 👌."]
const regexpCurrencyOrPunctuation = /\p{Sc}|\p{P}/gu;
console.log(sentence.match(regexpCurrencyOrPunctuation));
// Expected output: Array ["¥", "."]
语法
\p{loneProperty}
\P{loneProperty}
\p{property=value}
\P{property=value}
参数
loneProperty(独立属性)-
一个独立的 Unicode 属性名或值,其语法与
value相同。它指定General_Category属性的值,或一个二元属性名。在v模式下,它也可以是字符串的二元 Unicode 属性。注意:ICU 语法也允许省略
Script属性名,但 JavaScript 不支持这一点,因为大多数情况下Script_Extensions比Script更有用。 property(属性)-
一个 Unicode 属性名。必须由ASCII 字母(
A–Z,a–z)和下划线(_)组成,并且必须是非二元属性名之一。 value-
一个 Unicode 属性值。必须由 ASCII 字母(
A–Z,a–z)、下划线(_)和数字(0–9)组成,并且必须是PropertyValueAliases.txt中列出的受支持值之一。
描述
\p 和 \P 仅在Unicode 感知模式下受支持。在 Unicode 非感知模式下,它们是 p 或 P 字符的恒等转义。
每个 Unicode 字符都有一组描述它的属性。例如,字符a 具有 General_Category 属性,值为 Lowercase_Letter,以及 Script 属性,值为 Latn。\p 和 \P 转义序列允许你根据字符的属性进行匹配。例如,a 可以通过 \p{Lowercase_Letter}(General_Category 属性名是可选的)以及 \p{Script=Latn} 来匹配。\P 创建一个补集类别,它由不具有指定属性的代码点组成。
当设置了i 标志时,\P 字符类别在 u 和 v 模式下的处理方式略有不同。在 u 模式下,大小写折叠发生在减法之后;在 v 模式下,大小写折叠发生在减法之前。更具体地说,在 u 模式下,\P{property} 匹配 caseFold(allCharacters - charactersWithProperty)。这意味着 /\P{Lowercase_Letter}/iu 仍然匹配 "a",因为 A 不是 Lowercase_Letter。在 v 模式下,\P{property} 匹配 caseFold(allCharacters) - caseFold(charactersWithProperty)。这意味着 /\P{Lowercase_Letter}/iv 不匹配 "a",因为 A 甚至不在所有大小写折叠的 Unicode 字符集中。另请参阅补集类别和不区分大小写的匹配。
要组合多个属性,请使用启用 v 标志的字符集交集语法,或者参阅模式减法和交集。
在 v 模式下,\p 可以匹配一系列代码点,这在 Unicode 中定义为“字符串属性”。这对于表情符号最有用,表情符号通常由多个代码点组成。但是,\P 只能补充字符属性。
注意: 有计划将字符串属性功能也移植到 u 模式。
示例
通用类别
通用类别用于对 Unicode 字符进行分类,并且可以使用子类别来定义更精确的分类。在 Unicode 属性转义中可以使用短形式或长形式。
它们可用于匹配字母、数字、符号、标点符号、空格等。有关通用类别的更详尽列表,请参阅Unicode 规范。
// finding all the letters of a text
const story = "It's the Cheshire Cat: now I shall have somebody to talk to.";
// Most explicit form
story.match(/\p{General_Category=Letter}/gu);
// It is not mandatory to use the property name for General categories
story.match(/\p{Letter}/gu);
// This is equivalent (short alias):
story.match(/\p{L}/gu);
// This is also equivalent (conjunction of all the subcategories using short aliases)
story.match(/\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}/gu);
脚本和脚本扩展
有些语言使用不同的脚本作为其书写系统。例如,英语和西班牙语使用拉丁脚本书写,而阿拉伯语和俄语使用其他脚本(分别是阿拉伯语和西里尔语)。Script 和 Script_Extensions Unicode 属性允许正则表达式根据字符主要使用的脚本(Script)或根据它们所属的脚本集(Script_Extensions)来匹配字符。
例如,A 属于 Latin 脚本,ε 属于 Greek 脚本。
const mixedCharacters = "aεЛ";
// Using the canonical "long" name of the script
mixedCharacters.match(/\p{Script=Latin}/u); // a
// Using a short alias (ISO 15924 code) for the script
mixedCharacters.match(/\p{Script=Grek}/u); // ε
// Using the short name sc for the Script property
mixedCharacters.match(/\p{sc=Cyrillic}/u); // Л
有关更多详细信息,请参阅Unicode 规范、ECMAScript 规范中的脚本表和ISO 15924 脚本代码列表。
如果一个字符只在有限的脚本集中使用,那么 Script 属性将只匹配“主要”使用的脚本。如果我们要根据“非主要”脚本匹配字符,我们可以使用 Script_Extensions 属性(简称 scx)。
// ٢ is the digit 2 in Arabic-Indic notation
// while it is predominantly written within the Arabic script
// it can also be written in the Thaana script
"٢".match(/\p{Script=Thaana}/u);
// null as Thaana is not the predominant script
"٢".match(/\p{Script_Extensions=Thaana}/u);
// ["٢", index: 0, input: "٢", groups: undefined]
Unicode 属性转义与字符类别
使用 JavaScript 正则表达式,也可以使用字符类别,特别是 \w 或 \d 来匹配字母或数字。但是,这些形式只匹配拉丁脚本中的字符(换句话说,\w 匹配 a 到 z 和 A 到 Z,\d 匹配 0 到 9)。如这个例子所示,处理非拉丁文本可能会有点笨拙。
Unicode 属性转义类别涵盖了更多的字符,\p{Letter} 或 \p{Number} 将适用于任何脚本。
// Trying to use ranges to avoid \w limitations:
const nonEnglishText = "Приключения Алисы в Стране чудес";
const regexpBMPWord = /([\u0000-\u0019\u0021-\uFFFF])+/gu;
// BMP goes through U+0000 to U+FFFF but space is U+0020
console.table(nonEnglishText.match(regexpBMPWord));
// Using Unicode property escapes instead
const regexpUPE = /\p{L}+/gu;
console.table(nonEnglishText.match(regexpUPE));
匹配价格
以下示例匹配字符串中的价格
function getPrices(str) {
// Sc stands for "currency symbol"
return [...str.matchAll(/\p{Sc}\s*[\d.,]+/gu)].map((match) => match[0]);
}
const str = `California rolls $6.99
Crunchy rolls $8.49
Shrimp tempura $10.99`;
console.log(getPrices(str)); // ["$6.99", "$8.49", "$10.99"]
const str2 = `US store $19.99
Europe store €18.99
Japan store ¥2000`;
console.log(getPrices(str2)); // ["$19.99", "€18.99", "¥2000"]
匹配字符串
使用 v 标志,\p{...} 可以通过使用字符串属性来匹配可能长于单个字符的字符串
const flag = "🇺🇳";
console.log(flag.length); // 2
console.log(/\p{RGI_Emoji_Flag_Sequence}/v.exec(flag)); // [ '🇺🇳' ]
但是,你不能使用 \P 来匹配“不具有某个属性的字符串”,因为不清楚应该消耗多少个字符。
/\P{RGI_Emoji_Flag_Sequence}/v; // SyntaxError: Invalid regular expression: Invalid property name
规范
| 规范 |
|---|
| ECMAScript® 2026 语言规范 # prod-CharacterClassEscape |
浏览器兼容性
加载中…
另见
- 字符类指南
- 正则表达式
- 字符类:
[...]、[^...] - 字符类转义:
\d、\D、\w、\W、\s、\S - 字符转义:
\n、\u{...} - 析取:
| - 维基百科上的 Unicode 字符属性
- ES2018:RegExp Unicode 属性转义,作者:Dr. Axel Rauschmayer (2017)
- Unicode 正则表达式 § 属性
- Unicode 实用程序:UnicodeSet
- v8.dev 上带集合表示法和字符串属性的 RegExp v 标志 (2022)