正则表达式在处理字符串的模式匹配时十分灵活,但是由于其语法较为晦涩,比较复杂的正则写起来十分困难,而且可读性并不好,这也是灵活性带来的代价。当然有很多朋友都能写出很好的正则,但是对于像我这样的初学者,调试一条复杂的正则往往需要很多精力。一些个人经验下面慢慢讲。
正则表达式类似于编译原理中的表达式,有学过编译原理的同学其实不用很困难就可以入门,在处理正则表达式的时候,其实计算机也是先转化成DFA去做。对于使用者来说,不用深究其中的细节,知道语法和用法就可以了。下面就简单总结一下正则表达式的基本语法。
正则表达式其实是一段字符串,使用时用模式串,也就是正则表达式去匹配目标字符串。
下面列举几个常用的符号:
.:点号匹配一个除了换行符之外的字符
*:闭包,也就是零个或者多个集合,如a*匹配零个或者多个a,.*匹配零个或多个非换行符。
+:一个或多个表达式的集合
?:问号有多重含义。a?表示匹配一个或零个a;也可以表示非贪婪表达式,如a.*?b或者a{1,10}?b
\:转义符,或将下个字符变为特殊字符。\*表示*号,\\表示\。\s,\w等等。
\d:一位数字
\w:包含下划线、数字、字母的字符
\s:匹配任何空白字符,包含空格、换行符、制表符等
\t:一个制表符
\n:换行符
|:或关系
&:与关系
^:在开始处表示首符,如^a.*?b这个表达式去匹配bababa的话就没有结果。目标串的首符一定是a才行。在中括号中,^表示取反。如[^/s]表示所有非空白符。
[\s\S]:特别把这个拿出来,这个表示包括空白符、换行符的任意字符。因为点号不能匹配换行符,所以需要这种形式的写法。
括号:表示分组。
在Python中,正则表达式主要依靠re模块。在机制上跟java的正则表达式是十分类似的。同样是使用Pattern、Match这样的对象。有些方法比如是start(),end()等都是相同的。但是还是有一些不太一样的地方。
使用Python我们如果希望使用正则表达式,首先引入re模块。调用re.compile(regex),该方法返回一个pattern对象。即编译好的正则表达式,我们可以重复使用该pattern去做匹配,pattern的match方法返回一个Match的实例,调用match的group()方法输出匹配结果。使用方法如下:
pattern=re.compile(r'a.*?b')
match=pattern.match("acnb")
print(match.group())
这段代码输出的结果是acnb。
详细的部分引用一篇博文,写的很详细:http://blog.csdn.net/pleasecallmewhy/article/details/8929576
下面的脚本是一个从Html代码中抽取信息的一个Demo:
# #author="ACE_J"
"从文件中读取成绩信息,利用正则表达式抽取成绩列表并格式化输出到文件"
import os
import re
#读取文件函数
def readFile(fileName):
if os.path.exists(fileName):
file=open(fileName,"r")
content=file.read()
file.close()
return content
else:
return None
#得到当前系统换行符
ls=os.linesep
#main
content=readFile("e://info.dat")
afterContent=[]
pattern=r'<tr .*?>[\s\S]+?</tr>'#第一个模式,抽取元素<tr>...</tr>
for match in re.finditer(pattern,content):
pattern2=r'<td>(.*)</td>'#第二个模式,从每一个<tr>...</tr>中再抽取<td>...</td>
str1=match.group()
for match2 in re.finditer(pattern2,str1):
str2=re.subn(r'<[\s\S]+?>',"",match2.group(1))#将<td>之间的所有标签删除,剩下内容
afterContent.append(str2[0])#将抽取出来的内容写到缓存
afterContent.append("\t")
afterContent.append(ls)
fobj=open("e://after.dat","w")
fobj.write(''.join(afterContent))
fobj.close()
很简单的脚本,从文件中读取信息,利用正则表达式多次过滤。当然这个脚本可以只用一个表达式就写出来。但是我的水平不足,而且那样的表达式可读性并不好。所以有时候迭代一下不失为一个好办法,毕竟工具是为人所用,达到目的才是重要的。