乐哈哈旅游视频网:

中文正则式

$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单个汉字的正则,最后经过修正,成为本文开始给出的表达式。

posted on 2009-06-05 22:59  riky  阅读(2728)  评论(0编辑  收藏  举报

乐哈哈旅游视频网: