PHP匹配UTF-8中文字符的正则表达式

时间:2023-01-06 14:29:02

<script type="text/javascript"><!-- google_ad_client = "pub-0241434510974184"; /* auto-http.cn 右边 ,468x60 */ google_ad_slot = "0902256228"; google_ad_width = 468; google_ad_height = 60; // --></script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>

急着用的朋友可以先拿去用,这个正则非原创,但是经过我的修改,如有问题,请回复告知,代码是写给PHP初学者的,高手请自抠正则。

<meta http-equiv="Content-Type" Content="text/html; charset=utf-8">
<?php
$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编码的汉字 " ;
}
?>

先不要被上面那个稀奇古怪的代码吓到,看完这篇文章以后,你就不会觉得它了不起了:)另外,本文不会卖弄大量的关于编码的概念,如果需要额外的扩展阅读,请通过google查找,相信一定能够满足您的阅读需求。

关于编码:

上海的邮政编码是200000 ,上海的地理编码(经纬度)是lat:31.2356;lng:121.4728,上海的电话编码(国际区号)是:086021。类比在计算机里面,“汉”字的gb2312编码是:1011 1010 1011 1010(16进制:BABA);“汉”字的Unicode编码是 0110 1100 0100 1001(16进制:6C49);“汉”字的UTF-8编码是1110 0110 1011 0001 1000 1001 (16进制:E6B189)。所以,不同的汉字,在不同的编码方式下,表示的方法也是不一样的。

关于unicode:

随着全球化的到来,全球性的的沟通变得异常的普遍,在互联网的世界里,为了能够让用户方便的访问全世界不同地域,不同文字(编码)的站点,历史上先后有两个试图独立设计Unicode的组织,即国际标准化组织(ISO)和一个软件制造商的协会(unicode.org)。在1991年前后,双方都认识到世界不需要两个不兼容的字符集。于是它们开始合并双方的工作成果,并为创立一个单一编码表而协同工作。于是,真正意义上的Unicode孕育而生。

Unicode的学名是"Universal Multiple-Octet Coded Character Set",简称为UCS。UCS可以看作是"Unicode Character Set"的缩写。简单的说Unicode是一种可以容纳全世界所有语言文字的编码方案。

unicode编码在前面已经看到了,补充一点,有的时候还会用10进制中文字符,所以“汉”字还有可能是这个样子:27721

< script >
document . write ( " " . charCodeAt ()) ; //显示27721
<
/ script>

关于UTF-8:

UTF-8是unicode编码的扩展(也可以说是子集:Unicode Translation Format),由Ken Thompson于1992年创建,只要将某个字符的unicode编码一一插入相应的空位(刚好有16个空位)就可以成为一个UTF-8编码,细心的研究一下刚才给出的“汉”字的例子,你就能发现这一点。

1 1 1 0 _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _

好了,我们现在已经了解了关于unicode,编码和UTF-8的相关知识(虽然并不全面),但是我们还需要一些工具:

一个进制转换的页面(觉得麻烦的话可以google现成的):

< meta http - equiv = " Content-Type " Content = " text/html; charset=utf-8 " >
<
script >
var hex = new Array ( " 0 " , " 1 " , " 2 " , " 3 " , " 4 " , " 5 " , " 6 " , " 7 " , " 8 " , " 9 " , " A " , " B " , " C " , " D " , " E " , " F " ) ;
function CKparseInt ( n , r ) {
for ( var i = 0 ; i < n . length ; ++ i )
if ( n . charAt ( i ) >= r ) {
alert ( " 格式错 " ) ;
return 0 ;
}
if ( isNaN ( M = parseInt ( n , r )))
alert ( " 格式错 " ) ;
return M ;
}
function DecimaltoAnother ( A , radix ) {
s = "" ;
while ( A >= radix ) {
s += hex [ A % radix ] ;
A = Math . floor ( A / radix);
}
return transpose(s += hex[A]);
}
function transpose(s) {
N = s.length;
for (i = 0,t = ""; i < N; i++)
t += s.substring(N-i-1, N-i);
return t;
}
function EvalAny(item, r) {
M = CKparseInt(item.value, r);
for (var i = 0, MyForm = document.forms[0]; i < MyForm.length; ++i)
MyForm.elements[i].value = DecimaltoAnother(M, MyForm.elements[i].name.substr(1,3));
}
<
/ script >
<
center >
<
h3 >进制转换< / h3>
<br>
<form method="post">
<table border=0 align=center>
<tr>
<td align=right>
<p>二进制:<
/ p >
<
/ td>
<td><input name="b002" value="0" onChange="EvalAny(this, 2)" size=27><
/ td >
<
/ tr>
<tr>
<td align=right>三进制:<
/ td >
<
td >< input name = " t003 " value = " 0 " onChange = " EvalAny(this, 3) " size = 21 >< / td>
<
/ tr >
<
tr >
<
td align = right >五进制:< / td>
<td><input name="q005" value="0" onChange="EvalAny(this, 5)" size=16><
/ td >
<
/ tr>
<tr>
<td align=right>八进制:<
/ td >
<
td >< input name = " o008 " value = " 0 " onChange = " EvalAny(this, 8) " size = 12 >< / td>
<
/ tr >
<
tr >
<
td align = right >十进制:< / td>
<td><input name="d010" value="0" onChange="EvalAny(this, 10)" size=11><
/ td >
<
/ tr>
<tr>
<td align=right>十六进制:<
/ td >
<
td >< input name = " h016 " value = " 0 " onChange = " EvalAny(this, 16) " size = 8 >< / td>
<
/ tr >
<
/ table>
<
/ form >
<
/ center>

一份编码对照表:

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

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

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

4E00 :  0100 1110 0000 0000
9FA0 :  1001 1111 1010 0000

上面的二进制编码就是要写入1 1 1 0 _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _ 的16个空位,就像:

1110 0100 1011 1000 1000 0000
1110 1001 1011 1110 1010 0000

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

1110 0100 1011 1000 1000 0000 : E4 B8 80
1110 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单个汉字的正则,最后经过修正,成为本文开始给出的表达式。

http://www.csask.com/blog/?p=20

 
 
 
要激活 regexp 的支持在配置 PHP 时加上 --with-regex[=TYPE]。TYPE 可以是 system,apache 或 php 之一。默认使用 php。

PHP 的 Windows 版本已经内置该扩展模块的支持。无需加载任何附加扩展库即可使用这些函数。

运行时配置
本扩展模块在 php.ini 中未定义任何配置选项。

资源类型
本扩展模块未定义任何资源类型。

预定义常量
本扩展模块未定义任何常量。

范例
例子 1. 正则表达式例子

  1. <?php   
  2. // 如果在 $string 中任何地方找到 "abc" 则返回 &true;   
  3. ereg ("abc"$string);   
  4.   
  5. // 如果 $string 以 "abc" 开头则返回 &true;   
  6. ereg ("^abc"$string);   
  7.   
  8. // 如果 $string 以 "abc" 结尾则返回 &true;   
  9. ereg ("abc$"$string);   
  10.   
  11. // 如果用户浏览器是 Netscape 2,3 或 MSIE 3 则返回 &true;   
  12. eregi ("(ozilla.[23]|MSIE.3)"$HTTP_USER_AGENT);   
  13.   
  14. // 将三个空格分隔的单词放入 $regs[1],$regs[2] 和 $regs[3] 中   
  15. ereg ("([[:alnum:]]+) ([[:alnum:]]+) ([[:alnum:]]+)"$string,$regs);   
  16.   
  17. // 将 <br /> 标记放到 $string 开头   
  18. $string = ereg_replace ("^""<br />"$string);   
  19.   
  20. // 将 <br /> 标记放到 $string 结尾   
  21. $string = ereg_replace ("$""<br />"$string);   
  22.   
  23. // 删除 $string 中的所有换行符   
  24. $string = ereg_replace ("/n"""$string);   
  25. ?>