常见的正则表达式的文档都是关于英文(ASCII字符)的,英文开发者通常也只需要处理ASCII字符,不需要处理中文这类多字符的字符。不过,依照李处ASCII字符的方式处理中文字符,就有可能出错。

  举个例子,许多文档说点号.可以匹配“除换行符\n之外的任意字符”,单这可能只适用于单字节字符,因为点号匹配的其实只是“除换行符\n之外的任意字符”而已。

  Python 2

re.search(r"^.$", "发") != None     # => false

  PHP 4.x/5.x

preg_match("/^.$/", "发");          // => 0, 表示成功匹配的次数为0

  Ruby 1.8

"发" =~ /^.$/ != nil                # => false

  之所以会出现这种情况,是因为正则表达式在匹配时“看到”的字符串是多个字符(在UTF-8编码环境下占用3个字节;在GBK编码环境下占用2个字节),于是将它们全部视为单字节字符,而没有理解这几个字节表示的是“发”;因为点号.只能匹配一个字符,结果当然不能正确匹配。要解决这个问题,必须显示指定编码,让正则表达式处理程序正确识别多字节字符,Python中的做法是在字符串的开头的引号之前写上u字符。











点号.对 Unicode 字符的匹配

字符串 正则表达式 语言 是否显示指定 Unicode 模式 可否匹配
^.$ .NET
^.$ Java 否(无须指定)
^.$ Javascript 否(无法指定) 结果取决于浏览器
/^.$/ PHP
/^.$/u PHP
^.$ Python 2
^.$ Python 3
/^.$/ Ruby 1.8
/^.$/u Ruby 1.8
/^.$/ Ruby 1.9

  注1: PHP 和 Ruby 的正则表达式本身不包含分隔符(分隔符可以有很多种,常见的是反斜线/),但 PHP 指定 Unicode 模式必须在后一个分隔符之后写u,所以在这里将分隔符也写出来。

  注2:Python 2 中虽然提供了 Unicode 模式,但即便采用这种模式,点号.仍然不能匹配多字节字符,出非显示指定为 Unicode 字符串(在 Python 2,默认是 ASCII 字符串)

  注3:Ruby 1.9 在不同平台想的变现不一样,经过作者测试,在 Linux 下采用 Unicode 匹配规则,而 Mac 和 Windows 的情况通常是采用 ASCII 匹配规则。

  现在再来解释,虽然 GBK 编码也是多字节编码,为什么不推荐使用:常见的中文字符编码有 GBK 和 Unicode 两种, GBK 编码使用确实也很多(尤其是在 Windows 平台上),但如果需要使用正则表达式处理中文,我强烈推荐使用 Unicode 字符。这样的选择的最重要的原因是,正则表达式处理程序一般只能准确识别 Unicode 字符的边界

  举例来说:要求匹配“收”(GBK编码是ca d5)或者“发”(GBK编码是b7 a2),很自然会想到使用字符组[收发]。这个思路是对的,但从例 7-4 可以看到,即便采用GBK编码,正则表达式处理程序仍然不能识别出“2个字符节字符构成的字符组”,而将其视为“4个单字符字节构成的字符组”,其值分别为202、213、183、162,换算成十六进制,正好是“收”和“发”对应的ca、d5和b7、a2.用它来匹配没有指定Unicode编码的字符“罚”(它的GBK编码是b7 a3,也解释十进制的183 163),就会产生错误——虽然“罚”字既不等于“收”也不等于“发”,但码值为b7的这个单字符字符可以匹配!





正则表达式——推荐使用 Unicode 编码的更多相关文章

  1. [转]程序员趣味读物:谈谈Unicode编码

    from : http://pcedu.pconline.com.cn/empolder/gj/other/0505/616631_all.html#content_page_1 这是一篇程序员写给程 ...

  2. 转载:谈谈Unicode编码,简要解释UCS、UTF、BMP、BOM等名词

    转载: 谈谈Unicode编码,简要解释UCS.UTF.BMP.BOM等名词 这是一篇程序员写给程序员的趣味读物.所谓趣味是指可以比较轻松地了解一些原来不清楚的概念,增进知识,类似于打RPG游戏的升级 ...

  3. 根据Unicode编码用C#语言把它转换成汉字的代码

    rt 根据所具有的Unicode编码用C#语言把它转换成汉字的代码 var s = System.Web.HttpUtility.HtmlDecode(Utf8Str); var o = Newton ...

  4. 字体Unicode编码

    客专家福利     有奖试读&征文——我们在互联网上奋斗的故事      10月推荐文章汇总      加入“技术热心人”,赢丰厚奖品 html-中文字体在CSS中的显示(Unicode编码) ...

  5. Unicode编码

    Unicode为世界上所有的文字系统的每一个字符单位分配了一个唯一的整数,称为代码点,范围为:0~1114111: ASCII将每一索引映射为唯一的二进制表示,但Unicode允许多个不同二进制编码的 ...

  6. 推荐的PHP编码规范

    推荐的PHP编码规范 发布时间: 2014-05-7 浏览次数:2754 分类: PHP教程 推荐的PHP编码规范 一 编辑器设置 1. 使用Tab缩进,不要使用空格 鉴于很多编辑器在保存文件时会自动 ...

  7. PHP解码unicode编码中文字符代码示例

    在抓取某网站数据,结果在数据包中发现了一串编码的数据:"......\u65b0\u6d6a\u5fae\u535a......", 这其实是中文被unicode编码后了的数据,想 ...

  8. [百度空间] [转]程序员趣味读物:谈谈Unicode编码

    出处:CSDN [ 2005-05-13 10:05:53 ] 作者:fmddlmyy 这是一篇程序员写给程序员的趣味读物.所谓趣味是指可以比较轻松地了解一些原来不清楚的概念,增进知识,类似于打RPG ...

  9. GB2312、Unicode编码等

    抛出问题: 我在CPP文件中,打算输出一行阿拉伯字符:

随机推荐

  1. Qualcomm_Mobile_OpenCL.pdf 翻译-2

    2  Opencl的简介 这一章主要讨论Opencl标准中的关键概念和在手机平台上开发Opencl程序的基础知识.如果想知道关于Opencl更详细的知识,请查阅参考文献中的<The OpenCL ...

  2. 理解BurpSuit Intruder几种攻击方式

    Intruder标签下有四种攻击方式 Sniper Battering Ram Pitchfork Cluster Bomb 假设用户名密码词典分别如下: user1,user2,usre3 pass ...

  3. ARM仿真器之驱动黄色惊叹号

    JLink CDC UART PORT 黄色惊叹号 Windows 无法验证此设备所需的驱动程序的数字签名.某软件或硬件最近有所更改,可能安装了签名错误或损毁的文件,或者安装的文件可能是来路不明的恶意 ...

  4. DevExpress WinForms v19.1新版亮点:Tree List等控件性能增强

    行业领先的.NET界面控件DevExpress v19.1终于正式发布,本站将以连载的形式介绍各版本新增内容.在本系列文章中将为大家介绍DevExpress WinForms v19.1中新增的一些控 ...

  5. Linux系统中的硬件问题如何排查?(4)

    Linux系统中的硬件问题如何排查?(4) 2013-03-27 10:32 核子可乐译 51CTO.com 字号:T | T 在Linux系统中,对于硬件故障问题的排查可能是计算机管理领域最棘手的工 ...

  6. Keras class_weight和sample_weight用法

    搬运: https://stackoverflow.com/questions/57610804/when-is-the-timing-to-use-sample-weights-in-keras i ...

  7. JAVA笔记26-网络编程(不等于网站编程)

    一.网络基础(TCP/IP详解) 1.IP协议(Internet Protocol):网络层,支持网间数据报通信.无连接数据报传送,数据报路由选择和差错控制. IPv4 32位(4字节),IPv6 1 ...

  8. docker-compose简单使用

    1,下载安装docker-compose # http://get.daocloud.io/ curl -L https://get.daocloud.io/docker/compose/releas ...

  9. spring自带工具类

    在spring-core.jar包中,org.springframework.util package下有很多工具类,这些工具类十分具有参考意义.

  10. java总结1

    栈,堆,方法区.main和局部变量在栈,new 对象 在堆, 类和常量在方法区除了8大基础数据类型,其他都为引用变量局部变量在函数内或方法上声明,没有默认值,定义必须赋值一旦提供构造方法,就不会有默认 ...