2008.08.24 12:22 am rex
按:本文使用的RegexBuddy为3.1.0(完全)版,并非最新版3.1.1(截至2008.08.23)。需要该版本的请在这篇文章后留言。
注:参考www.regular-expressions.info的风格,更新了本模板的style.css文件,加入了与正则式代码相关的格式:
- 正则式格式举例:[a-z]+@[a-z]+?\.[a-z]+
- 匹配格式举例:pig@animals.com和chicken@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.com和chicken@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,最后一个汉字的模样。
此序列的第一位,U+4e00,是汉字一。
自定义:到目前为止,相当于给汉字找到了官方的身份和说法,使用\p{InCJK_Unified_Ideographs}就能匹配所有的中文字符。我们其实也可以将一些重复出现的东西,封装起来,以备使用。例如,对于阿拉伯数字,我们有\d可以用。对于中文数字一二三四等等,我们有没有办法呢?
$zh_digit=qr/一|二|三|四|五|六|七|八|九|十|零|〇|百|千|万|亿|佰|仟|壹|贰|叁|肆|伍|陆|柒|捌|玖|拾/;
$str="人民币五十一万零三百元整。大写:伍拾壹万零三佰元整。";
while($str =~ s/((?:$zh_digit)+)//)
{
print $1."\n";
} |
其输出结果见附图。
结论
可以使用\p{InCJK_Unified_Ideographs}匹配任意中文字符。在不支持该种标记方式时,也可以使用[\u4e00-\u9fa5]加以匹配。
关于文正则表达式,我觉得尚未穷其奥秘。以前在linux(utf8编码)下,编写scim输入平台的郑码码表时,匹配中文所使用的正则表达式为[\x80-\xff]{3},也能很好地工作。请参阅此文:龙文郑码码表 for scim。其原理我尚不清楚,留待之后有时间研究。如有知情者,也请不吝赐教,先行谢过。
2008.08.17 12:02 pm rex
偶然从网上找到该教程,下载后觉得不错,可以作为《精通正则表达式》的番外篇,共同学习。
关于此视频的讲师:
此视频的讲师为余晟先生。余先生是抓虾网高级顾问。毕业于东北师范大学,主修计算机,辅修中文。现居北京。曾任高级程序员、技术经理;从事过大量文本解析和数据抽取的工作。对程序语言、算法、数据库和敏捷开发都有兴趣,译有《精通正则表达式》(第3版)一书。
关于此视频
此视频分为5讲,每讲30分钟左右,内容深入浅出,适合以下受众:
- 对正则式感兴趣的人;
- 对正则式不感兴趣的人;
- 正则式初学者,想入门;
- 正则式有所成者,想提高。
当然,如果能静下心来,通读《精通正则表达式》原书,并亲自动手尝试,效果更为显著。
目录及下载:
视频文件(avi格式)已经使用7-zip压缩,使其总尺寸从784Mb减小到74.7Mb。您需要使用支持7-zip的解压软件才能打开。
上传空间在mediafire。在网络封锁日益严峻的大环境下,您或许需要使用代那个理才能访问。我不敢保证此文件址长时有效。需要下载的请抓紧时间。
2008.11.04更新:
由于mediafire不出意料被AND(不幸言中),上面的文件也无法下载。好在还有纳米盘。请访问牛腩的学习空间去使用纳米盘下载。上面除了我这里提到的5部分《精通正则表达式》vedio以外,还有两段“实战正则表达式”,还不赶紧去看看?
2008.08.08 10:36 am rex

无论对于正则式初学者还是老手,如果想从头至尾了解各种正则式流派之差异,深究正则式之匹配原理,打磨高效率的正则式,《精通正则表达式》(豆瓣链接)都是不二之选。但是该书长处在于推理、演绎,归纳倒在其次,虽然也有不少表格,但是作者一再强调,不要把本书仅仅当作参考手册来读。因为正则式参考手册另有其书:《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发到您的邮箱。
2008.07.28 10:18 am rex
原来在FireFox2.x中使用过一个插件FindBar,十分好用。升级到firefox3.0之后,FB居然冬眠。今天终于看到更新,能继续在firefox中使用了,心情超爽,特写日志以记之。
意译一下作者的介绍。插件主页、介绍原文在这里。
——————-正则表达式分割线——————
/Find Bar/
/Find Bar/ is a new extension for Firefox that is still a little bit in progress. I’ve always believed that one of the best features of Firefox is it’s quick find bar. I probably use it about 20 times a day, if not more. But it has to be said its a fairly simple beast. When it comes to more powerful searches you’re just out of luck. This extension adds a whole new dimension to the find bar, regular expressions. The regular expressions are implemented using the JavaScript engine so check the JavaScript RegExp syntax for the full details.
/Find Bar/是FireFox的新插件,目前仍在完善中。对于firefox,我一直觉得它方便快捷的搜索栏是其亮点之一。我每天使用该功能20次以上。但是必须承认,其搜索功能太过薄弱。当你要搜索更复杂的内容时,它就无能为力了。
本插件为搜索栏添加了新选项:正则表达式。它使用了JavaScript正则式引擎。请查询JavaScript RegExp文档来了解语法细节内容。
有待解决的两个问题:
- Whitespace. HTML is made up a lot of this, most of it is ignored by the browser and not visible on the page. At the moment this extension doesn’t ignore anything so you may find there are more spaces between words than you expected. Should I err on the side of accuracy as it is now, or collapse all whitespace?空白符(水平制表符、空格等)。HTML中包含了许多空白符,其中一大部分被浏览器忽略掉,不在页面上显示出来。目前该插件没有忽略任何字符,因此你会发现,单词之间往往有更多的空白符符。我是该精确地显示出每个空白字符呢,还是该将其全部压缩?
- Block content. The standard find bar wont find searches that span blocks (paragraphs in human terms). This extension does, which while potentially useful also causes some issues. One thought is to make each paragraph like a line then you can use line breaks to match paragraphs as you might expect.区块内容。标准的搜索栏不会跨区块(亦即段落)搜索,而本插件搜索时却会跨越区块,这既是便利之处,但是也有可能带来副作用。一种思路是将每一段落处理为一个文本行,这样您就可以使用换行符来匹配段落。
该插件的兼容性
| FireFox |
 |
2.0b1 - 3.1a2pre |
| ThunderBird |
 |
2.0 - 3.0a1 |
下载地址
Install v1.0.1
(Installs from addons.mozilla.org)
——————-正则表达式分割线——————
跨区块搜索我觉得不是大问题,对于空白字符,我的解决方法是,只要是使用正则表达式来搜索,就在使用空格时使用\s+来表示。这样,从内容上,它表示了任何种类的空白字符;从数量上,它表示了最少一个(多则不限)的空白字符,既不错杀,也无冤死。
由此引发的感慨是:人的眼睛所能看到的字符是有限的,其所看到内容与事实的真相有时未必相符。而程序是精确的,每一个比特都明察秋毫。(例如在汇编语言中的数字0与ASCII字符’0′就截然不同。虽然在perl中,两者单独出现时被视为是同一事物。)
该插件还能结合原搜索栏的全部高亮显示选项来显示,便于显示所有的匹配。在搜索英文等外语时,你会发现这一点十分有用。
另外有一点得陇望蜀的心思是,如果该插件支持保存常用搜索就好了。比方搜索email地址的、URL的,日期的,诸如此类。虽如此,这款插件已经十分好用,强烈推荐。
2008.07.13 10:01 pm rex
有人在正则表达式中文站贴出这样一道问题:
求ASP 用户名 表达式
用户名长度在2-20字符之间,由中文/大小写字母/数字/中划线-/下线线_组成。
这个问题不算难,只要下边一行核心代码就能搞定:
"^[-_a-zA-Z0-9\u4e00-\u9fa5]{2,20}$" |
关键是没有使用过ASP语言。按此页的提示,设置了ASP环境。查询了一些在线的入门级ASP教程之后,解答如下:
<form action="verify.asp" method="post">
姓名:
<input name="name" type="text" />
<input name="Submit" type="submit" value="提交" />
<input name="Submit2" type="reset" value="重置" />
</form> |
它调用以下verify.asp文件:
<%
Function RegExpTest(patrn, strng)
Dim regEx, retVal ' 建立变量。
Set regEx = New RegExp ' 建立正则表达式。
regEx.Pattern = patrn ' 设置模式。
regEx.IgnoreCase = False ' 设置是否区分大小写。
retVal = regEx.Test(strng) ' 执行搜索测试。
If retVal Then
RegExpTest = "合法用户名。"
Else
RegExpTest = "非法用户名。"
End If
End Function
name=request.form("name")
psw=request.form("psw")
sex=request.form("sex")
city=request.form("city")
Response.write RegExpTest("^[-_a-zA-Z0-9\u4e00-\u9fa5]{2,20}$", name)
%> |
运行界面见附图。
另外,还有一些正则表达式可供参考:
匹配中文字符的正则表达式:
匹配双字节字符(包括汉字在内)正则表达式:
匹配空行的正则表达式:
匹配HTML标记的正则表达式:
/ <(.*)> .* <\/\1> | <(.*) \/> / |
匹配首尾空格的正则表达式:
用正则表达式限制只能输入中文:
onkeyup= "value=value.replace(/[^\u4E00-\u9FA5]/g, ' ') " onbeforepaste= "clipboardData.setData( 'text ',clipboardData.getData( 'text ').replace(/[^\u4E00-\u9FA5]/g, ' ')) " |
用正则表达式限制只能输入全角字符:
onkeyup= "value=value.replace(/[^\uFF00-\uFFFF]/g, ' ') " onbeforepaste= "clipboardData.setData( 'text ',clipboardData.getData( 'text ').replace(/[^\uFF00-\uFFFF]/g, ' ')) " |
用正则表达式限制只能输入数字:
onkeyup= "value=value.replace(/[^\d]/g, ' ') "onbeforepaste= "clipboardData.setData( 'text ',clipboardData.getData( 'text ').replace(/[^\d]/g, ' ')) " |
用正则表达式限制只能输入数字和英文:
onkeyup= "value=value.replace(/[\W]/g, ' ') "onbeforepaste= "clipboardData.setData( 'text ',clipboardData.getData( 'text ').replace(/[^\d]/g, ' ')) " |