惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
L
LangChain Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
罗磊的独立博客
J
Java Code Geeks
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 叶小钗
小众软件
小众软件
博客园 - Franky
D
Docker
Google DeepMind News
Google DeepMind News
Microsoft Azure Blog
Microsoft Azure Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
U
Unit 42
宝玉的分享
宝玉的分享
C
Check Point Blog
B
Blog
V
V2EX
博客园 - 三生石上(FineUI控件)
MyScale Blog
MyScale Blog
The Cloudflare Blog
博客园 - 聂微东
博客园_首页
Engineering at Meta
Engineering at Meta

博客园 - riky

右键cmdshell DBLINK使用实战 oracle 日期相关的东东和几个应用的例子 - riky - 博客园 vnc.conf 1521 error1 - riky - 博客园 多项目同步进行“交叉编译” HIBERNATE 多表查询的解决方案 - riky - 博客园 动态添加SWAP分区 消息处理2 消息处理1 vs2008 程序 xp风格 - riky REWRITE DEBUG... - riky - 博客园 ssi conf. SSI2 SSI 大型-WEBSITE建设资料2 大型WEB-SITE建设资料 cygwin中 unable get setup.ini from... 的错误问题 NetPerf 计划
中文正则式 - riky - 博客园
riky · 2009-06-05 · via 博客园 - riky

$word = "中文";
if (preg_match("/^([".chr(228)."-".chr(233)."]{1}[".chr(128)."-".chr(191)."]{1}[".chr(128)."-".chr(191)."]{1}){1}/",$word) == true || preg_match("/([".chr(228)."-".chr(233)."]{1}[".chr(128)."-".chr(191)."]{1}[".chr(128)."-".chr(191)."]{1}){1}$/",$word) == true || preg_match("/([".chr(228)."-".chr(233)."]{1}[".chr(128)."-".chr(191)."]{1}[".chr(128)."-".chr(191)."]{1}){2,}/",$word) == true)
{
echo "很好,这是一个UTF-8编码的汉字";
}
else
{
echo "抱歉,这不是一个UTF-8编码的汉字";
}


UTF-8是unicode编码的扩展(也可以说是子集:Unicode Translation Format),由Ken Thompson于1992年创建,只要将某个字符的unicode编码一一插入固定的16个空位就可以成为一个UTF-8编码
1 1 1 0 _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _

“汉”字的gb2312编码是:1011 1010 1011 1010(16进制:BABA);“汉”字的Unicode编码是 0110 1100 0100 1001(16进制:6C49);“汉”字的UTF-8编码是1110 0110 1011 0001 1000 1001 (16进制:E6B189)

111001101011000110001001
1110____10______10______
    0110  110001  001001

一份编码对照表:

http://www.ansell-uebersetzungen.com/gbuni.html

准备好以后,我们就开始DIY匹配UTF-8中文字符的正则表达式,有能力的朋友可以不阅读下面的文章,自己对照正则表达式判断和分析过程(我一开始就是这么做的!),下面的进度比较快,对编码不了解的朋友需要借助参考资料阅读。

仔细研究《编码对照表》,你会发现unicode编码中的汉字编码区间是连续的,位于4E00和9FA0之间,用《进制转换页面》把16进制转换成2进制:

4E00 :  0100 1110 0000 00009FA0 :  1001 1111 1010 0000
上面的二进制编码就是要写入1 1 1 0 _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _ 的16个空位,就像:

1110 0100 1011 1000 1000 00001110 1001 1011 1110 1010 0000
将新组成的2进制形式UTF-8编码使用《进制转换页面》整理成16进制的(分析过程使用)格式:

1110 0100 1011 1000 1000 0000 : E4 B8 801110 1001 1011 1110 1010 0000 : E9 BE A0
精确拆分的结果如下:

第一段:E4 B8 80 到 E4 BF BF
第二段:E5 80 80 到 E8 BF BF
第三段:E9 80 80 到 E9 BE A0

正则的作者显然是为了编写的方便,将汉字的UTF-8编码集扩大为了:E4 80 80 到 E9 BF BF ,在对使用效果影响不大的情况下,我们也不妨简化处理:

[".chr(228)."-".chr(233)."]{1}表示一个E4(228的16进制表示)到E9之间的编码,[".chr(128). "-".chr(191)."]{1}表示80到BF之间的编码,于是就组成了 ([".chr(228)."-".chr(233)."]{1}[".chr(128)."-".chr(191)."]{1}[".chr(128). "-".chr(191)."]{1}){1}这个匹配UTF-8单个汉字的正则,最后经过修正,成为本文开始给出的表达式。