Python标准库 re
正则表达式 regular expression 用来匹配一系列符合句法规则的字符串,是一门独立的小型的语言,如果你了解类Unix系统,那么你对正则表达式就一定不陌生。正则表达式的概念最初是由Unix中的工具普及开的(如: sed grep)。Python中也内嵌了正则表达式,通过re模块实现。正则表达式有什么用?例如你需要从一大段Html代码中把Email地址或图片链接等过滤出来,那么正则表达式就很有用。
主内容: Python标准库01 正则表达式re包
出处: Vamei 博客 http://www.cnblogs.com/vamei
因为归纳的比较直观,不需要再重写一篇。
补充
正则表达式中,group() 用来提出分组截获的字符串,( )包围了一个小的正则表达式。
>>> a = '123abc456' >>> re.search("(\d{3})([a-z]{3})(\d{3})",a).group(0) '123abc456' >>> re.search("(\d{3})([a-z]{3})(\d{3})",a).group(1) '123' >>> re.search("(\d{3})([a-z]{3})(\d{3})",a).group(2) 'abc' >>> re.search("(\d{3})([a-z]{3})(\d{3})",a).group(3) '456'
一些正则用法:
>>> s= r'abc' #定义一个规则 >>> re.findall(s,'ababc123abc') #字符串中满足规则便会返回结果,如果不符合,返回一个空列表 ['abc','abc'] >>> re.findall(s,'abaaaaaaaa') []
转义 (如果需要匹配的字符串之中包含元字符怎么办?)
>>> r = r"\^\$abc" # \^ \$ 把^和$的特殊含义转义掉了 >>> str = "^$abc abc ^abc $abc" >>> re.findall(r,str) ['^$abc']
元字符
[ ]
>>> str = "top tip tap ttp tep" >>> r1 = r"t[io]p" # t和p之间要么有i 要么有o >>> re.findall(r1,str) ['top', 'tip']
>>> r1 = r"t[^io]p" #在[]中字母前加 ^ 便表示取反 >>> re.findall(r1,str) ['tap', 'ttp', 'tep']
^ 和 $
>>> str = "name is , abcss" >>> r = r"^na" >>> re.findall(r,str) ['na'] >>> >>> str = "name is , bob" >>> r = r"bob$" >>> re.findall(r,str) ['bob']
* 前一个字符重复0次或多次
>>> r =r"aa*" >>> re.findall(r,'ab') ['a'] >>> re.findall(r,'aaaaaa') ['aaaaaa'] >>> re.findall(r,'aa') ['aa'] >>> re.findall(r,'a') ['a']
+ 匹配一次或多次,至少一次
>>> r =r"aa+" >>> re.findall(r,'aa') ['aa'] >>> re.findall(r,'ab') [] >>> re.findall(r,'aaaaa') ['aaaaa'] >>> re.findall(r,'a') []
? 匹配一次或0次,常表示可有可无
>>> r = r"^010-*\d{8}$" >>> re.findall(r,'010-12345678') ['010-12345678'] >>> re.findall(r,'01012345678') ['01012345678'] >>> re.findall(r,'010-----12345678') #这样无限输入也可以,不是我们需求的 ['010-----12345678'] >>> r = r"^010-?\d{8}$" >>> re.findall(r,'01012345678') ['01012345678'] >>> re.findall(r,'010-12345678') ['010-12345678'] >>> re.findall(r,'010---12345678') []
贪婪与非贪婪模式影响的是被量词修饰的子表达式的匹配行为,贪婪模式在整个表达式匹配成功的前提下,尽可能多的匹配,而非贪婪模式在整个表达式匹配成功的前提下,尽可能少的匹配
贪婪模式
>>> r = r'what+' >>> re.findall(r,'whatttttttttttt') ['whatttttttttttt']
非贪婪模式 ? 加在重复的后面可以做最小匹配
>>> r = r'what+?' >>> re.findall(r,'whatttttttttttt') ['what']
re 常用函数
findall() 找到匹配的所有字符串,并把它们作为一个列表返回
search() 扫描字符串,找到匹配的位置
match() 扫描字符串,匹配开头
>>> reg = re.compile(r'what') >>> reg.findall('abcwhat') ['what']
>>> reg.match('abcwhat') # 没有匹配的内容则返回空 >>> reg.match('whatabc') <_sre.SRE_Match object at 0x7f7d63e8c3d8>
>>> reg.search('abcwhat') # match和search的区别是match只匹配开头 <_sre.SRE_Match object at 0x7f7d63e8c440> >>> reg.search('abcwh')
finditer() 找到匹配的所有字符串,并把它们作为一个迭代器返回
>>> s = reg.finditer('abcwhat what vvvwhat') >>> s.next() # 返回的居然是match对象 <_sre.SRE_Match object at 0x7f7d63e8c440> >>> s.next() <_sre.SRE_Match object at 0x7f7d63e8c3d8> >>> s.next() <_sre.SRE_Match object at 0x7f7d63e8c440> >>> s.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration >>>
re.sub() 字符串的replace()方法并不支持正则,我们需要用re.sub()来做替换
>>> s = "hello what" >>> s.replace('w..t','world') 'hello what' >>> >>> r = r'w..t' >>> re.sub(r,'world',s) 'hello world'
re.split()
>>> s = "123-456=789+000*111" >>> re.split(r'[\+\-\=\*]',s) #有些符号有特殊含义,需要转义一下 ['123', '456', '789', '000', '111']
编译标志 flags
DOTALL,S 使.匹配包括换行在内的所有字符
IGNORCASE,I 使匹配对大小写不敏感
LOCALE,L 做本地化识别 ,支持英文字母外其他语言的字母
MULTILINE,M 多行匹配,影响 ^和$
VERBOSE,X 能够使用REs的verbose状态,使之被组织的更清晰易懂
re.S
>>> r = r'google.com' >>> re.findall(r,'google.com') ['google.com'] >>> re.findall(r,'googledcom') ['googledcom'] >>> re.findall(r,'googlexcom') ['googlexcom'] >>> >>> re.findall(r,'google\ncom') [] >>> re.findall(r,'google\ncom',re.S) ['google\ncom'] >>> re.findall(r,'google\tcom',re.S) ['google\tcom'] >>>
re.I
reg = re.compile(r'what') #如果我们要让what不区分大小写,怎么办? [Ww[Hh][Aa][Tt] 显然很麻烦,利用re包中的一个属性 re.I 可以不区分大小写. reg = re.compile(r'what',re.I)
re.M
>>> s = """ ... what abc ... abcwhat ... defwhat ... whatnnn ... """ >>> r = r"^what" >>> re.findall(r,s) #发现什么都没有,因为字符串是以换行符储存的 [] >>> s '\nwhat abc\nabcwhat\ndefwhat\nwhatnnn\n\n'
>>> re.findall(r,s,re.M) ['what', 'what']
re.X
>>> tel = r""" #这样定义会很直观 ... \d{3,4} ... -? ... \d{8} ... """ >>> re.findall(tel,'010-87654321') [] >>> re.findall(tek,'010-87654321',re.X) ['010-87654321']
分组 ( .... )
>>> email = r"\w{3}@\w+(\.com|\.cn)" # \w+表示一个字母以上 |表示或,但是还需要加分组(),分组表示里面包含一个小正则 >>> re.match(email,'abc@google.com') <_sre.SRE_Match object at 0x7f7d63e995d0> >>> re.match(email,'abc@google.cn') <_sre.SRE_Match object at 0x7f7d63e99648> >>> re.match(email,'abc@google.org') >>> re.findall(email,'abc@google.com') # 有分组 findall会先返回分组的 ['.com']
>>> print s asasrc=name com sakdak sad src=what com adad addq >>> >>> r = r'src=.+ com' >>> re.findall(r,s) ['src=name com', 'src=what com'] # 如果我只想返回src= 后面的字符串呢?
>>> r = r'src=(.+) com' >>> re.findall(r,s) ['name', 'what']
图片来自 http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html