一个关于Python正则表达式的快速使用手册
一直在纠结自己的博客到底应该写一些什么东西,这几天发现自己的正则用的不是很熟练,于是想要写一篇关于正则表达式的博客,目的就是为了让自己以后要用而又不会的时候不至于像无头苍蝇一样到处乱撞。
有些人在碰到问题时,就像:“我知道,我可以使用正则表达式。”现在,他们就有了两个问题。(Jamie “jwz” Zawinski,1997年8月 Netscape和Mozilla.org的创始人之一)
jwz所说的两个问题:一个就是要解决的问题,一个就是如何使用正则表达式解决问题------这本身就是个问题了,由此可见学会并熟练使用正则表达式是多么的重要~~~
因为我主要是使用Python,所以先说明在Python中是通过re模块来支持正则表达式。
re模块中有许多强大的方法:
函数/方法 | 描述 |
compile(pattern,flags=0) | 使用任何可选的标记来“编译”正则表达式模式,返回一个正则表达式对象 |
match(pattern,string,flags=0) | 尝试使用正则表达式匹配字符串,如果匹配成功,就返回匹配对象,如果失败就返回None |
search(pattern,string,flags=0) | 使用可选标记搜索字符串中第一次出现的正则表达式模式,如果匹配成功就返回匹配对象,如果失败就返回None |
findall(pattern,string[,flags]) | 查找字符串中所有(非重复)出现的正则表达式模式,返回一个匹配列表 |
finditer(pattern,string[,flags]) | 与fandall相同,但返回的不是列表,而是一个迭代器。每一次迭代返回一个正则表达式对象 |
split(pattern,string,max=0) | 根据正则表达式的模式分隔符,将字符串分割为列表,然后返回成功匹配的列表,分割最多操作max次(默认是分割所有) |
sub(pattern,repl,string,count=0) | 使用repl替换正则在字符串中匹配到的位置,除非自定义count,否则就替换所有匹配到的位置 |
purge() | 清除隐式编译的正则表达式模式 |
group(num=0) | 返回整个匹配对象,或者编号为num的子组 |
groups(default=None) | 返回一个包含所有匹配子组的元组,如果没有匹配到就返回空元组 |
groupdic(default=None) | 返回一个包含所有匹配的命名子组的字典,所有的子组名称作为字典的key,如果没有匹配到就返回一个空字典 |
compile()函数是用来编译正则表达式的,所以从match()说起
使用match()方法匹配字符串
>>> import re >>> m = re.match('foo','foo') >>> m.group() #使用group()方法返回匹配结果 'foo' #证明匹配失败返回None >>> m = re.match('foo','fll') >>> m.group() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'NoneType' object has no attribute 'group' None类型没有group属性,就是说m是None
#match是从字符串开始部分匹配,也就是f对应f,o对应o,所以匹配成功
>>> re.match('foo','food').group()
'foo'
#而这个例子里从开始匹配的话,f对应s,所以匹配失败
>>> re.match('foo','sfood').group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
上述例子中foo匹配sfood失败,但foo却实实在在存在于sfood中,这里就要用search()使用搜索而不是去匹配
>>> m = re.search('foo','sfood') >>> m.group() 'foo'
group()与groups()的使用示例:
>>> m = re.match('(\w\w\w)-(\d\d\d)','abc-123') >>> m.group() 'abc-123' >>> m.group(1) 'abc' >>> m.group(2) '123' >>> m.groups() #groups只匹配子组,也就是加()的那些内容 ('abc', '123')
匹配邮箱的示例:
>>> re.match('\w+@\w+\.com','awmpy@qq.com').group() 'awmpy@qq.com'
findall()和finditer()的使用示例:
>>> s = 'This and that' >>> re.findall(r'(th\w+)',s,re.I) ['This', 'that'] #findall返回的就是列表 >>> it = re.finditer(r'(th\w+)',s,re.I) #生成一个迭代器 >>> g = it.__next__() >>> g.groups() ('This',) #groups返回值是一个元组,g每次迭代取一个值 >>> g.group(1) 'This' >>> g = it.__next__() >>> g.groups() ('that',) >>> g.group(1) 'that' >>> [g.group(1) for g in re.finditer(r'(th\w+)',s,re.I)] #使用列表解析形成列表 ['This', 'that'] >>>
sub()和subn()函数使用示例:
>>> re.sub('[ae]','X','abcdef') 'XbcdXf' >>> re.subn('[ae]','X','abcedf') ('XbcXdf', 2) >>>
split()函数的使用
re.split()实际上在Python中str对象也有split属性,但是re.split的存在就是因为他可以结合re的扩展匹配,完成比较复杂的分割
>>> import re >>> DATA = { ... 'Mountain View, CA 94040', ... 'Sunnyvale, CA', ... 'Los Altos, 94606', ... 'Cupertino 95401', ... 'Palo Alto CA', ... } >>> for item in DATA: ... print(re.split(', |(?= (?:\d{5}|[A-Z]{2})) ', item)) ... ['Mountain View', 'CA', '94040'] ['Cupertino', '95401'] ['Sunnyvale', 'CA'] ['Los Altos', '94606'] ['Palo Alto', 'CA'] >>> #使用正向前视断言将','还有后边是两个大写字母和5个数字的空格用','分割开