正则表达式-regular_expression难点易错点

Regular Expression难点易错点

Javascript匹配所有中文字符

最开始用法:/[\u4e00-\u9fa5]/

/[\u4e00-\u9fa5]/的意思是匹配所有从U+4E00, cjk unified ideograph-4e00U+9FA5, cjk unified ideograph-9fa5的字符。这一段区域对应的是 Unicode 1.0.1 就收录进来的中日韩统一表意文字(CJK Unified Ideographs)区块,在 Unicode 3.0 加入扩展 A 区以前,这个正则表达式确实给出了所有汉字的编码。然而时光飞逝,Unicode 在2017年6月发布了10.0.0版本。在这20年间,Unicode 添加了许多汉字。比如 Unicode 8.0 添加的 109 号化学元素「鿏(⿰⻐麦)」,其码点是 9FCF,不在这个正则表达式范围中。而如果我们期望程序里的/[\u4e00-\u9fa5]/可以与时俱进匹配最新的 Unicode 标准,显然是不现实的事情。

因此,ECMAScript提供了一个无需维护的正则表达式:/\p{Unified_Ideograph}/u

其中\u是 ECMAScript 2015 定义的正则表达式标志,意味着将表达式作为 Unicode 码点序列。\p是ECMAScript 2018 定义的正则表达式 Unicode 属性转义,它赋予了我们根据 Unicode 字符的属性数据构造表达式的能力。Unified_Ideograph是 Unicode 字符的一个二值属性,对于汉字,其取值为 Yes,否则为 No。因此\p{Unified_Ideograph}匹配所有满足Unified_Ideograph=yes的 Unicode 字符,而它的底层实现由运行时所依赖的 Unicode 版本决定,开发者不需要知道汉字的具体 Unicode 码点范围。

此外,还有/\p{Ideographic}/u/\p{Script=Han}/u这两种匹配方式。但是它们匹配了除了汉字以外的其他一些字符,在「汉字匹配正则表达式」这个需求下,是错的。

比如/\p{Ideographic}/u这个属性表明该字符属于 CJKV 表意文字或者与汉语书写相关的其他表意文字(如西夏文、女书),这个属性粗略地定义了「中文字符」的分类。使用/\p{Ideographic}/u来匹配汉字会过于宽泛。一是包含了西夏文、女书,二是只用于编码转换用的兼容字符也纳入其中。

/\p{Script=Han}/u囊括了所有统一表意文字、中日韩兼容性字符、苏州码子、「〇」、「〆」、「々」以及字典常用的部首。从汉文(Han Script)与汉字(CJK Ideograph)的关系我们可以知道,/\p{Script=Han}/u匹配的是汉文作为一个字符集里面的所有字符,因此它包括了部首、「々」等字符,这些字符要么当它们独立存在的时候没有语言意义(部首独立存在是一个符号),要么无法独立存在(「々」依赖于所修饰的汉字)。所以汉字是汉文的一个单元,汉文除了包含汉字以外,还包括这些符号、数字、修饰符。因此使用/\p{Script=Han}/u来匹配汉字是混淆了汉文与汉字的概念范围。