深柳堂

探索匹配中文的正则表达式

按:本文使用的RegexBuddy为3.1.0(完全)版,并非最新版3.1.1(截至2008.08.23)。需要该版本的请在这篇文章后留言。

注:参考www.regular-expressions.info的风格,更新了本模板的style.css文件,加入了与正则式代码相关的格式:

  • 正则式格式举例:[a-z]+@[a-z]+?\.[a-z]+
  • 匹配格式举例:pig@animals.comchicken@birds.com
  • 普通文本格式举例:这是一些普通文本。hello regex world. pig@animals.com和chicken@birds.com

可以这样使用:在字符串这是一些普通文本。hello regex world. pig@animals.com和chicken@birds.com使用正则式[a-z]+@[a-z]+?\.[a-z]+加以匹配,得到的结果为:pig@animals.comchicken@birds.com

极端粗放型:点号其实是近乎万能的,可以匹配任何字符,限制只在于换行符的匹配上。匹配中文自然不在话下。作为可有可无的背景符,一个.*就能匹配掉包括中文在内的全部字符。这当然是一种极端的情况,因为这样显示不出中文字符串的特性。这不是本文要探讨的。

极端集约型:如果搜索特定文本,例如在一二三四五六七八九十拾佰百千仟万亿中匹配十拾, 直接使用m/十拾/就能搞定。这同样不是本文要探讨的。与\w能匹配英文字母一样,本文想找的是能够匹配所有汉字,而不匹配其它文本的一种简写方式。

普适型型:由于汉字属于Unicode,我们就从unicode里面找。在Unicode Regular Expressions,列出了unicode的许多种表达方式。搜索chinese,找到如下一行:

Writing Systems Blocks
Chinese CJK Unified Ideographs, CJK Unified Ideographs Extension A, CJK Compatibility Ideographs, CJK Compatibility Forms, Enclosed CJK Letters and Months, Small Form Variants, Bopomofo, Bopomofo Extended

关于CJK的含义,是指中日韩统一表意文字(Chinese Japanese Korean Unified Ideographs),可以参考百度释义,或wiki词条。

再查了一下regular expressions,查到其unicode一节有这样的内容:

\p{InCJK_Unified_Ideographs}: U+4E00..U+9FFF

看到这里,我想起了以前写的《匹配用户名的asp正则表达式(包括中文)》一文中,提到的中文匹配为[\u4e00-\u9fa5],原来是有其对应的速记方式的,虽然两者有最后一组字符的差异。看附图可见U+9fa5,最后一个汉字的模样。我爱正则表达式|在RegexBuddy中如何使用正则表达式匹配中文字符|http://iregex.org 此序列的第一位,U+4e00,是汉字

自定义:到目前为止,相当于给汉字找到了官方的身份和说法,使用\p{InCJK_Unified_Ideographs}就能匹配所有的中文字符。我们其实也可以将一些重复出现的东西,封装起来,以备使用。例如,对于阿拉伯数字,我们有\d可以用。对于中文数字一二三四等等,我们有没有办法呢?

$zh_digit=qr/一|二|三|四|五|六|七|八|九|十|零|〇|百|千|万|亿|佰|仟|壹|贰|叁|肆|伍|陆|柒|捌|玖|拾/;
 
$str="人民币五十一万零三百元整。大写:伍拾壹万零三佰元整。";
while($str =~ s/((?:$zh_digit)+)//)
{
	print $1."\n";
}

我爱正则表达式|在RegexBuddy中如何使用正则表达式匹配中文字符|http://iregex.org

其输出结果见附图。

结论

可以使用\p{InCJK_Unified_Ideographs}匹配任意中文字符。在不支持该种标记方式时,也可以使用[\u4e00-\u9fa5]加以匹配。

关于文正则表达式,我觉得尚未穷其奥秘。以前在linux(utf8编码)下,编写scim输入平台的郑码码表时,匹配中文所使用的正则表达式为[\x80-\xff]{3},也能很好地工作。请参阅此文:龙文郑码码表 for scim。其原理我尚不清楚,留待之后有时间研究。如有知情者,也请不吝赐教,先行谢过。

《精通正则表达式》视频教程提供下载

偶然从网上找到该教程,下载后觉得不错,可以作为《精通正则表达式》的番外篇,共同学习。

关于此视频的讲师:

此视频的讲师为余晟先生。余先生是抓虾网高级顾问。毕业于东北师范大学,主修计算机,辅修中文。现居北京。曾任高级程序员、技术经理;从事过大量文本解析和数据抽取的工作。对程序语言、算法、数据库和敏捷开发都有兴趣,译有《精通正则表达式》(第3版)一书。

关于此视频

此视频分为5讲,每讲30分钟左右,内容深入浅出,适合以下受众:

  • 对正则式感兴趣的人;
  • 对正则式不感兴趣的人;
  • 正则式初学者,想入门;
  • 正则式有所成者,想提高。

当然,如果能静下心来,通读《精通正则表达式》原书,并亲自动手尝试,效果更为显著。

目录及下载:

视频文件(avi格式)已经使用7-zip压缩,使其总尺寸从784Mb减小到74.7Mb。您需要使用支持7-zip的解压软件才能打开。

上传空间在mediafire。在网络封锁日益严峻的大环境下,您或许需要使用代那个理才能访问。我不敢保证此文件址长时有效。需要下载的请抓紧时间。

章节 内容 大小(Mb) 链接
第一讲 15.5 点此下载
第二讲 13.1 点此下载
第三讲 16.6 点此下载
第四讲 15.3 点此下载
第五讲 13.9 点此下载
源代码 16.9Kb 点此下载

2008.11.04更新:
由于mediafire不出意料被AND(不幸言中),上面的文件也无法下载。好在还有纳米盘。请访问牛腩的学习空间去使用纳米盘下载。上面除了我这里提到的5部分《精通正则表达式》vedio以外,还有两段“实战正则表达式”,还不赶紧去看看?

提供《正则表达式袖珍参考书》英文第二版pdf下载

我爱正则表达式|《精通正则表达式》英文第三版PDF提供下载
无论对于正则式初学者还是老手,如果想从头至尾了解各种正则式流派之差异,深究正则式之匹配原理,打磨高效率的正则式,《精通正则表达式》(豆瓣链接)都是不二之选。但是该书长处在于推理、演绎,归纳倒在其次,虽然也有不少表格,但是作者一再强调,不要把本书仅仅当作参考手册来读。因为正则式参考手册另有其书:《OReilly.Regular.Expression.Pocket.Reference》(豆瓣链接)。

该书与《精通正则表达式》同出自O’Reilly,第二版发行于2007年。我找到了pdf版,1M左右,排版精良。涵盖的语言有:

  • Perl 5.8,
  • Java(java.util.regex),
  • .NET and C#,
  • PHP,
  • Python,
  • Ruby,
  • JavaScript,
  • PCRE,
  • Apache Web Server,
  • vi Editor, Shell Tools。

上述每一种语言/工具都分别单独有一章来详细介绍其正则特性。相比之下,《精通正则表达式》中只有Perl、PHP、Java、.Net有此殊荣。

阅读建议:

  • 精通正则表达式》有情节有起伏,有推理有结论,有感悟有启发,可以当作小说,从头读到尾(至少前6章如此)。
  • 《正则表达式袖珍参考书》就是一本迷你的正则式百科全书。可以当字典、当语法书来读。

该书128页,一本小册子而已。售价US $14.99,或CAN $17.99。如果您囊中不羞涩,强烈建议你购买正版。如果您只是抱着纯学术目的钻研一下正则技术,可以先从这里下载电子版,记得及时删除哦。以下地址必有一款适合您;有的或许需要代理才能访问。如果使用代理也无法访问时,可以留言,我会把pdf发到您的邮箱。

Hosting URL
Fs2You click here
MediaFire click here
SkyDrivev click here