python正则表达式

正则表达式(regular expression)是一个伟大的东东,借助于正则表达式强大的功能,我们可以用更短的代码完成更丰富的功能。
最近帮助乖乖完成了一个利用正则表达式进行日志统计的功能脚本。里面很多复杂的功能用Python re模块写起来发现简洁和方便了许多,用着用着也发现了一些使用的心得和体会,特此来这里总结一下。


总体上来讲,我们使用正则表达式,一般都是用于以下几个用途:


匹配:检查某个字符串是否符合某种规则,比如,看看str里是否包含有“2011-09-15”这样子的日期字段,或者说有没有像“cat”,”dog”这样子的字段。一些同学可能要有些疑问了,那我在原字符串中直接find(“2011-09-15″),find(“cat”),find(“dog”)不就可以了嘛,干嘛搞得这么复杂。的确没错,对于特定的字符串的查找任务,用字符串子字符查找功能不失为一种更快的解法,但对于另些更通用的情况来说,正则表达式却似乎是惟一的解,比如,我们要找出字符串中是否包含“YYYY-MM-DD”这样子规则的日期数据,或者”cat”,”caat”,”caaaat”这样子的cat拼写,我们求助于正则表达式是正确和明智的。
查找:第二种功能,我们希望从字符串中找到符合某些规则的内容出来,在上面的例子中,可能我们光光知道句子中包含着”YYYY-MM-DD”这样的日期信息还不满足,我们希望能从句子中那提取出具体的日期信息来,正则表达式也非常适合这样子的工作。
查找全部:此外,有些时候某项规则出现次数可能不惟一,我们还需要把这种规则的信息统统找到的话,正则表达式也能够胜任。
提取:最后,是本人用得比较中意的功能:在现实的数据处理过程中,不同的字段一般有着不同的规则,如日期字段通常就是“YYYY-MM-DD”样子,而时间字段通常是”hh:mm”样子的,仅仅能够将信息一次从字符串中提取出来当然是非常好的,如果能在取出内容的时候按照字段的具体内容加上对应的名字,那就再好不过了。
假设我们手头有一份这样子的数据需要做处理,可以看出这是看出这是一份某人活动log,


今天开始记日记
2011-08-15 07:30 [大早上的被热醒,囧]
中间一段时间工作忙,没心情写啦~~~
2011-09-01 18:00 [晚上去看电影]
2011-09-10 15:00 [下午回学校看望了老师们]

2011-09-12 11:00 [今天是中秋节,早上学着做猪蹄,味道还不错]


可以看出这份日志格式有些凌乱,包含着不少杂乱的信息,但还有一些有规则的内容,如像“2011-09-10 15:00 [下午回学校看望了老师们]” 这种信息,日志内容是规则的YYYY-MM-DD hh:mm [$content] 形式的,假设这些内容保存于一个文本文件log.txt中,我们通过file(‘log.txt’).readlines()将日志的内容读入到一个数据lines后,我们该如何利用python中的正则表达式re模块来完成上述的功能呢?


匹配:我们如何找出所有的有效日志行?
查找:我们如何找出做过的事情
查找全部:我们如何找出全部做过的事情?
提取:我们如何将日期,时间,以及事情一次取出并按‘date’,’time’,'task’ 取得相应的信息?
对于匹配,我们如何找出那些以YYYY-MM-DD开头的日志行呢?


logs = file('log.txt').readlines()import re#一个用于正则表达式匹配的pattern#这个pattern满足4个数字-2个数字-2数字这样子的规则pattern = re.compile('\d{4}-\d{2}-\d{2}.*')for log in logs: if pattern.match(log): print log
可以看到在第7行那里\d表示数字,即[0-9],{4}表示重复4次,\d{4}就是表示重复4次的连续数字串,剩下的部分也比较好理解。看得出这个pattern其实对于一些无效的年份也是有效的,比如2011-99-99这样子的日子也是符合这种模式的,不过幸在我们处理的数据中没有出现这样子的情况,但大家不妨再想想如何才算是一个有效的日期的匹配模式 


对于二个查找的问题,我们如何找出日志中所有所做的事情呢?


logs = file('log.txt').readlines()import re#找出由[]包围着的任意字符串pattern = re.compile('\[.*\]')for log in logs: m = pattern.search(log) if m: print m.group()
可以看到屏幕上会输出做过的各种事情。


对于第三种任务,有时候,一些模式会在所要处理的信息中不止出现一次,我们又该如何得到我们想要的所有信息呢?比如,假设我们的所有日志没有了换行符,变成了是一行,我们又该如何得到所有的做过的事情?


logs = file('log.txt').readlines()import re#待处理的信息为一个整行s = ' '.join(logs)pattern = re.compile('\[(.*)\]')for info in pattern.findall(s): #找到所有满足需求的信息 print info
(.*)的意思是说,告诉re模块我们想要的内容只是[]包含着的内容,对[]本身不感兴趣


最后,提取问题,我们如何将日志信息中的日期、时间、事情等信息一起拿出来呢?


logs = file('log.txt').readlines()import re#一次处理找出日期、时间、事情三样信息pattern = re.compile("(?P<date>\d{4}-\d{2}-\d{2})\s+(?P<time>\d{2}:\d{2})\s+\[(?P<task>.*)\]")for log in logs: m = pattern.search(log) if m: print m.group('date'),m.group('time'),m.group('task')
其中(?P<name> pattern)就是把匹配的pattern放入到匹配结果中,并且用name做为这个变量的key。


OK,相信讲到这里应该对于python正则表达式几个常用的功能有了一定的了解,对于一些基本任务都应该能很好的cover到,不过要深究regular expression的细节,还是要找一些好的参考资料来看看,比如这本《精通正则表达式》。

你可能感兴趣的:(python正则表达式)