设为首页 收藏本站
查看: 449|回复: 0

[经验分享] PHP匹配UTF-8中文字符的正则表达式

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2017-4-9 12:45:51 | 显示全部楼层 |阅读模式
  
<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.value = DecimaltoAnother(M, MyForm.elements.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







php 扩展正则表达式函数 ereg



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

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

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

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

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

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


view plaincopy to clipboardprint?






  • <?php

  • //如果在$string中任何地方找到"abc"则返回&true;

  • ereg("abc",$string);



  • //如果$string以"abc"开头则返回&true;

  • ereg("^abc",$string);



  • //如果$string以"abc"结尾则返回&true;

  • ereg("abc$",$string);



  • //如果用户浏览器是Netscape2,3或MSIE3则返回&true;

  • eregi("(ozilla.[23]|MSIE.3)",$HTTP_USER_AGENT);



  • //将三个空格分隔的单词放入$regs[1],$regs[2]和$regs[3]中

  • ereg("([[:alnum:]]+)([[:alnum:]]+)([[:alnum:]]+)",$string,$regs);



  • //将<br/>标记放到$string开头

  • $string=ereg_replace("^","<br/>",$string);



  • //将<br/>标记放到$string结尾

  • $string=ereg_replace("$","<br/>",$string);



  • //删除$string中的所有换行符

  • $string=ereg_replace("/n","",$string);
  • ?>

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-362425-1-1.html 上篇帖子: 原:PHP内核源码分析:isset与 empty 下篇帖子: PHP发明人谈MVC和网站设计架构
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表