由正则式反推文本:REExtractor
Feb 2nd
发现一款简单有趣的正则表达式应用:REExtractor,作用是输入正则表达式,输出符合正则式描述的文本。作者给的介绍是
Generate all possibilities of Regular Expression,即生成正则表达式的所有可能性。不过,理论上可以做到,执行时却有限制。
一些限制
- 平台是GAE,语言是python,因此用的是python正则。或需代理才能访问使用。
- 支持的元字符或缩写:(), [],{m,n},{n},|,\w,\d。如果需要用到这些字符的字面值,请使用反斜线转义之。其中这里的\w等同于[a-zA-Z0-9],为62个字符之一,而不是通常意义上的包括下划线在内的[_a-zA_Z0-9],63字符之一。但是可以用[_\w]来代替,没问题的。
- 不支持的元字符:.(点号),^,$,\b,\D,\W,\1…(后向引用), (?=…), (?!…), (?<=…), (?<!…)等。
- 如果出现.点号,则直接输出。
- 如果使用^, $, \b, \1, (?=…), (?!…), (?<=…), (?<!…), 程序无视之。
- 如果使用\D或\b或[^],则程序会报错。原因是范围太宽。
- 不支持可能性在1000条以上结果的正则表达式。例如,\w{2},因为它的可能性是62×62。但是你可以使用\w\d,因为它的可能性是62×10。
它能做什么

好吧,虽然限制多多,但是你仍然可以拿它来做一些有趣的应用。下面略举两例。
- 生成一些简单的邮箱地址。试一下这条正则式:[abc]{3}\d@1(26|63).com ,它生成540条邮箱地址。
- 生成一些人名。试一下这条正则式:张[小大勇赞强战海][虎猫龙彪平]。它生成35条人名。是的,它支持中文,并且每个中文字都可以当成一个字符来应用。如果你家要添一个宝宝,可以将一些可能的字排列一下,看看哪些组合比较赏心、顺口,再从中选择一个。
平心而论,上面的这些小应用,当然可以直接编程实现,限制更少,更灵活,更强大。但是有必要每次都开编译器么?尝试一下这款小程序,也挺有趣的。而且,上一节中提及的一些限制,其实也是蛮有道理的。毕竟从正则式反推文本,用不到大多数的零宽断言(不过\1这种反向引用应该挺常用的,却不支持)。当作一个小玩具就好。
效率问题
Oct 22nd
上周发了篇《两条与密码验证相关的正则表达式问题》。今天看了些python的正则表达式,心血来潮,想看看这几种正则哪种效率较高。代码、运行结果见下。这是为什么呢?
#!/usr/bin/python import re import time import fpformat Regex1 = re.compile("^(?=[0-9a-zA-Z@%&]*\d)(?=[0-9a-zA-Z@%&]*[a-zA-Z])(?=[0-9a-zA-Z@%&]*[@%&])[0-9a-zA-Z@%&]{8,}$", re.MULTILINE) Regex2 = re.compile("^(?=.*\d)(?=.*[a-zA-Z])(?=.*[@%&])[0-9a-zA-Z@%&]{8,}$", re.MULTILINE) Regex3 = re.compile("^(?![0-9a-z]{8,16}$|[@%&]{8,16}$)[a-z0-9@%&]{8,16}$", re.IGNORECASE |re.MULTILINE) TimesToDo = 1250; TestString = "" for i in range(800): TestString += "aba134babdedfg@&%\n" StartTime = time.time() for i in range(TimesToDo): Regex1.search(TestString) Seconds = time.time() - StartTime print "R1 takes " + fpformat.fix(Seconds,3) + " seconds" StartTime = time.time() for i in range(TimesToDo): Regex2.search(TestString) Seconds = time.time() - StartTime print "R2 takes " + fpformat.fix(Seconds,3) + " seconds" StartTime = time.time() for i in range(TimesToDo): Regex3.search(TestString) Seconds = time.time() - StartTime print "R3 takes " + fpformat.fix(Seconds,3) + " seconds"
使用饭否新版API编写批量抓取饭否消息的程序
Jan 6th
我在断断续续地写一款抓饭程序。预想的功能包括:下载、更新饭否消息,搜索,统计。
近日饭否官方释出搜索功能,可以使用关键字搜索自己曾经发布的消息。作离线版的饭否消息管理工具,似乎没有必要。不过,有的网友习惯将饭否消息列到blog上,因此,我的程序还是有用的。
我原来写的程序,时间都消耗在饭否消息的下载、解析上。好在饭否新版API提供了任意页码的饭否消息,大大简化了抓取难度,因此编写一款饭否消息管理工具不再是一件难事。以python语言为例,我把自己的思路写出来,供各位有类似兴趣的朋友参考。
饭否消息解析之从minidom到xpath
Oct 14th
抛板砖,引白玉:为何不用xpath,什么是xpath?
最近拾起了以前的小项目,在完善上篇文章发布后,“那个谁”的回复让我很感兴趣。他问,“为什么不用xpath?”
xpath是什么东东?我反问。反问之前,当然少不了先google一番,以免……那个啥。
Read the rest of this entry »
饭否消息析取之regex vs xml
Oct 8th
页内导航:
批量导出饭否程序的方法很多,但是基本思路都是先将该网页保存到本地,然后将有用的饭否消息析取出来。本文不讨论如何下载饭否网页了(使用迅雷、wget、curl等),重点讨论对于下载到本地的网页,如何将有用的饭否消息析取出来。
匹配中文的正则表达式
Jun 2nd
以前在编写linux下的scim郑码码表时,就跟正则式的中文匹配问题打过交道。当时总结了这样一条经验,utf8编码格式下,中文正则式应该这样书写:
[\x80-\xff]{3}
当然,这与语言无关。在perl与python中,都是一样的。
现在,这条正则式又派上用场了。正在编写的一个小程序MiniBlogs Updater中,需要计算用户所输入的文字字数。因为中英文字符编码长度不一,如果直接使用python中的len()函数,它计算的是该字串的实际长度,一个中文字并非等同于一个英文字母的。因此,需要把中文字当成英文字母来处理。
我写了这样一条语句来处理:
length=len(re.sub('[\x80-\xff]{3}','a',msg))
它的意思是,把所有的中文都替换成英文字母a,然后再统计字数。(只是统计而已,不修改源字串。)这条语句在windows下utf8文件中能够正常工作。
再分享两则与匹配中文的正则表达式有用的链接:
python正则表达式链接
May 26th
最近迷上了python,对它的三重引号赞不绝口,原来在Perl中一直困扰我的utf8字串问题,在python中得到圆满解决。我指的是一直在写的fanfou应用程序中,发送私信的编码问题。调用饭否API向饭否发送普通消息没有问题,因为它兼容utf8与gb2312;而发送私时,却只允许使用utf8编码。最见效的例子是发“联通”两个字。
闲话打住,切入正题,说一说python中的正则式。推荐两个网址:
- Python正则表达式操作指南,由A.M. Kuchling(amk@amk.ca)原创,由FireHare翻译,发布在ubuntu.org.cn上。该文档可以当作手册来查阅。
- Dive into python中的正则式在线文档,发布在啄木鸟上。该文档深入浅出,以例子入手,适合当作自学教材。
在《mastering regular expressions》一书中perl与php都拿出整整一章来讲解,唯独没有python的单独章节。好在既然已经知道了正则式的大概,剩下的只是查语法就是了,上面的第一个链接足矣。
另外再引用一下《mastering regular expressions》中的原话:
I thought I knew regular expressions until I read Mastering Regular Expressions. Now I do.
神往精通正则表达式的境界。

Comments