首页/开发/正则与编码速查/Unicode 属性在正则中的使用

Unicode 属性在正则中的使用

Unicode 属性类让正则按字符属性匹配:\p{L} 匹配任意字母、\p{Han} 匹配汉字、\p{Script=Latin} 限定文字系统;是否支持、写法与大小写敏感度依引擎而不同,是不确定时最容易出错的一类语法。

正则与编码速查开发更新于 2026-10-17
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌‌‌​‌‌‌​‌​‌​‌‌​‌‌‌​​‌‌​‌​​‌​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​​‌​​​‌‌​​‌​‌​​‌​‌‌​‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌​‌​‌‌‌​​​​​‌‌‌​​‌​​‌‌​‌‌‌‌​‌‌‌​​​​​‌‌​​‌​‌​‌‌‌​​‌​​‌‌‌​‌​​​‌‌‌‌​​‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​

属性类的两种维度

属性类把「字符集合」从手动枚举改成按属性引用:一类是通用类别(如 \p{L} 字母、\p{Nd} 十进制数字、\p{M} 组合标记),另一类是脚本或文字系统(如 \p{Han} 汉字、\p{Greek}、\p{Cyrillic})以及区块(如 \p{InCJK_Unified_Ideographs})。它们能显著提升可读性与覆盖面,但支持程度差异很大:PCRE、Java、.NET、JavaScript 的支持范围与写法各不相同,Go 与 Python 标准库只能用部分形式。使用前必须确认目标引擎的实际能力。

基本信息

通用类别\p{L} 字母、\p{Ll} 小写、\p{Nd} 数字、\p{M} 标记等
脚本属性\p{Han} 汉字、\p{Greek} 希腊文、\p{Cyrillic} 西里尔文
区块属性按区块引用,如 \p{InBasic_Latin} 等写法因引擎而异
否定写法大写 P 表示取反,如 \P{L} 表示非字母
引擎差异PCRE/Java/.NET 支持较全;JavaScript 需 u 标志;Go 与 Python 标准库受限
常见替代不支持属性类时改用显式字符范围或以代码逻辑判断类别

典型使用场景

  • 多语言校验:判断是否字母、数字、汉字,而不依赖 ASCII 假设
  • 文本清洗:过滤组合标记、不可见格式字符或非目标脚本字符
  • 结构化抽取:从混合文本中提取连续汉字或连续拉丁字母
  • 安全过滤:以脚本白名单限制用户名可用文字范围
  • 兼容旧引擎:确认目标环境支持程度,必要时退回显式范围写法

常见写法示例

常见写法示例
# 引擎支持属性类时(示意见各引擎文档):
#   ^\p{L}+$            仅字母(含汉字等其他字母类)
#   \p{Han}             汉字
#   ^\P{M}+$            不含组合标记
# Python 标准库 re 不支持 \p{...},可用 unicodedata 判断类别
python -c "import unicodedata as u; print(u.category('中'), u.category('A'), u.category('1'))"   # Lo Ll Nd
python -c "import re; print(bool(re.match(r'^[^\W\d_]+$', '中文abc', re.UNICODE)))"            # 用 \w 反推字母
python -c "import re; print(re.findall(r'[\u4e00-\u9fff]+', 'abc 中文 def'))"                 # 显式范围匹配汉字

常见属性写法

写法含义注意点
\p{L} / \pL任意字母(含汉字)写法随引擎变化,部分引擎不支持简写形式
\p{Ll} / \p{Lu}小写 / 大写字母汉字属 Lo,不在此列
\p{Nd}十进制数字不等同于所有数字类,还有 No、Nl 子类
\p{M}组合标记文本清洗重点,删除会改变字形
\p{Han}汉字脚本部分引擎需写作 Script=Han
\P{...}取反可用于排除特定类别或脚本
属性类的语义取决于引擎使用的 Unicode 数据版本:同一表达式在旧版引擎上可能不匹配新字符。跨系统校验必须固定双方使用的引擎与版本,或改用显式字符范围以换取确定性。
用属性类做安全过滤要格外小心:属性覆盖范围很广(例如 \p{L} 包含大量非拉丁字母与历史字符),用「属于某属性」当白名单可能放进不在预期内的字符。安全场景应结合字符白名单、归一化与长度限制。
JavaScript 需要 u 标志才启用 Unicode 相关能力,且早期只支持 \p{...} 的通用类别与脚本属性;Go 的 regexp 用 \p{...} 引用 Unicode 类别但不支持全部语法。具体支持列表以各引擎官方文档为准。

易错点

  • 在不支持属性类的引擎上使用 \p{...}:直接编译失败或被当成字面量 → 先查引擎能力,或改用显式范围与代码判断
  • 假定 \w 在所有引擎里都含 Unicode 字母:部分引擎默认为 ASCII,汉字被排除 → 明确使用属性类或显式范围
  • 用属性当白名单做安全校验:范围过宽,放进非预期字符 → 叠加白名单与长度限制并做归一化
  • 忽略引擎的 Unicode 数据版本:新字符漏匹配,跨系统结果不一致 → 固定版本或用确定性写法
  • 把汉字当作大写或小写字母:汉字属 Lo 类别,大小写相关属性匹配不到 → 使用 \p{L} 或脚本属性

数据来源与参考

  • Unicode 官方:属性与正则类别的对应关系(UTS #18 相关)
  • PCRE / Java / .NET 官方文档:Unicode 属性支持说明
  • ECMAScript 规范:Unicode 属性转义与 u 标志

整理校对:其其网ICT文档中心 · 本页地址:docs.qiqicto.com/regex/unicode-regex-property.html

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌‌‌​‌‌‌​‌​‌​‌‌​‌‌‌​​‌‌​‌​​‌​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​​‌​​​‌‌​​‌​‌​​‌​‌‌​‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌​‌​‌‌‌​​​​​‌‌‌​​‌​​‌‌​‌‌‌‌​‌‌‌​​​​​‌‌​​‌​‌​‌‌‌​​‌​​‌‌‌​‌​​​‌‌‌‌​​‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​