正则表达式——推荐使用 Unicode 编码
常见的正则表达式的文档都是关于英文(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 编码的更多相关文章
- [转]程序员趣味读物:谈谈Unicode编码
from : http://pcedu.pconline.com.cn/empolder/gj/other/0505/616631_all.html#content_page_1 这是一篇程序员写给程 ...
- 转载:谈谈Unicode编码,简要解释UCS、UTF、BMP、BOM等名词
转载: 谈谈Unicode编码,简要解释UCS.UTF.BMP.BOM等名词 这是一篇程序员写给程序员的趣味读物.所谓趣味是指可以比较轻松地了解一些原来不清楚的概念,增进知识,类似于打RPG游戏的升级 ...
- 根据Unicode编码用C#语言把它转换成汉字的代码
rt 根据所具有的Unicode编码用C#语言把它转换成汉字的代码 var s = System.Web.HttpUtility.HtmlDecode(Utf8Str); var o = Newton ...
- 字体Unicode编码
客专家福利 有奖试读&征文——我们在互联网上奋斗的故事 10月推荐文章汇总 加入“技术热心人”,赢丰厚奖品 html-中文字体在CSS中的显示(Unicode编码) ...
- Unicode编码
Unicode为世界上所有的文字系统的每一个字符单位分配了一个唯一的整数,称为代码点,范围为:0~1114111: ASCII将每一索引映射为唯一的二进制表示,但Unicode允许多个不同二进制编码的 ...
- 推荐的PHP编码规范
推荐的PHP编码规范 发布时间: 2014-05-7 浏览次数:2754 分类: PHP教程 推荐的PHP编码规范 一 编辑器设置 1. 使用Tab缩进,不要使用空格 鉴于很多编辑器在保存文件时会自动 ...
- PHP解码unicode编码中文字符代码示例
在抓取某网站数据,结果在数据包中发现了一串编码的数据:"......\u65b0\u6d6a\u5fae\u535a......", 这其实是中文被unicode编码后了的数据,想 ...
- [百度空间] [转]程序员趣味读物:谈谈Unicode编码
出处:CSDN [ 2005-05-13 10:05:53 ] 作者:fmddlmyy 这是一篇程序员写给程序员的趣味读物.所谓趣味是指可以比较轻松地了解一些原来不清楚的概念,增进知识,类似于打RPG ...
- GB2312、Unicode编码等
抛出问题: 我在CPP文件中,打算输出一行阿拉伯字符:
随机推荐
- 索尼展示基于MicroLED技术的16K显示屏:约780吋
尽管 8K 彩电刚刚在消费级市场崭露头角,更极致的 16K 却已不慌不忙地登场了. 在日前于拉斯维加斯举办的 NAB 2019 展会上,索尼就秀出了旗下的 16K 显示设备,它目前正在日本横滨的资生堂 ...
- Spring学习之设计模式,动态代理和gclib动态代理
传统的代理模式是静态代理,也就是在方法区域中写入方法. 而动态代理的作用是,不修改实现类的代码,能够在代码的前后或者抛出异常的前后执行某个方法. 动态代理类的实现 //Interface public ...
- Vue基础第二章
1.数据绑定与数据声明 Vue中的数据绑定就是让与Vue实例绑定的DOM节点或script标签内的变量之间数据更新互相影响,即数据绑定后Vue实例的数据修改会使DOM节点的数据或者script标签内的 ...
- Web service基础
Web service是Web应用程序 平台是XML+http XML是不同平台和不同编程语言之间的语言,用于编解码数据. http是因特网协议 XML是web service的基础 Web serv ...
- Linux下vim显示行数
在Linux环境下的编辑器有vi.vim.gedit等等.进入这些编辑器之后,为了方便我们需要编辑器显示出当前的行号,可偏偏编辑器默认是不会显示行号的.我们有二种办法可以解决: 第一种是,手动显示:在 ...
- Flask【第10篇】:自定义Form组件
自定义Form组件 一.wtforms源码流程 1.实例化流程分析 1 # 源码流程 2 1. 执行type的 __call__ 方法,读取字段到静态字段 cls._unbound_fields 中: ...
- 微信小程序-自制弹出框禁止页面上下滑动
弹出 fixed 弹窗后,在弹窗上滑动会导致下层的页面一起跟着滚动. 解决方法: 在弹出层加上 catchtouchmove 事件 两种方法:(在电脑上测试是没有用的,这是触摸事件.因此,需要在手机端 ...
- Iconfont 阿里图库使用(小程序和H5)
前言 现在前端发展的太快,前端优化也是,图片也是被近2年来比较火的就是阿里图库取代了,不管小程序还是H5 都在用 好了,那么就介绍下如何使用吧 阿里图库 当然需要你到阿里官网 http://www.i ...
- Python开发WebService--使用soaplib库
Python开发WebService--使用soaplib库 使用soaplib开发基于Python语言的WebService主要有以下四个步骤:一.准备环境 S1:下载插件Python.s ...
- [每日一讲] Python系列:字典
#! /usr/bin/python # coding:utf-8 """ DATA STRUCTURE Container: Mapping (Another cont ...