理解 Javascript,PHP,SQL 匹配中文姓名正则表达式的区别
如何定义合法姓名
中文姓名非常多样化,想要真正区别出姓名和非姓名非常困难,但在这篇文章中,作为前提,我们认为合法的中文姓名由 1~10 个中文字符组成。
Javascript
知道了这个前提,容易得出 JS 的正则表达式——
1 | /^([\u4e00-\u9fa5]{1,10})$/ |
通俗解释:
^
匹配开头;\u4e00
代表第一个汉字“一”;\u9fa5
代表最后一个汉字“龥”;[\u4e00-\u9fa5]
匹配一个中文字符;{1,10}
这个中文字符出现 1 到 10 次;$
匹配结尾。
测试一下——
1 | const CHINESE_NAME_PATTERN = /^([\u4e00-\u9fa5]{1,10})$/; |
PHP
PHP 中不认 \u4e00
,需要稍微变换一下语法——
1 |
|
结尾的 u 是什么意思?官方文档 中有描述:
u (PCRE_UTF8)
此修正符打开一个与 perl 不兼容的附加功能。 模式和目标字符串都被认为是 utf-8 的。 无效的目标字符串会导致 preg_* 函数什么都匹配不到; 无效的模式字符串会导致 E_WARNING 级别的错误。 PHP 5.3.4 后,5字节和6字节的 UTF-8 字符序列被考虑为无效(resp. PCRE 7.3 2007-08-28)。 以前就被认为是无效的 UTF-8。
MySQL
SQL 中也无法直接写 Unicode 转义 \u4e00
,需要使用 HEX 将汉字转哈希之后,再匹配汉字的哈希值。
汉字的 HEX 范围:E4B880
~ E9BEA5
,所以可以用 e[4-9][0-9a-f]{4}
代表一个中文字符。
1 | SELECT HEX('一'); # 'E4B880' |
拓展
细心的读者可能会发现,HEX 输出的是大写字母 E
,为什么匹配的时候用的是小写字母 e
?其实这也是 MySQL 正则与 JS 正则的不同之一。
SQL 中,REGEXP
是不区分大小写匹配,REGEXP BINARY
是区分大小写匹配。
JS 中,/.../
是区分大小写匹配,/.../i
是不区分大小写匹配。
理解 Javascript,PHP,SQL 匹配中文姓名正则表达式的区别