?
?的作用,表示0或者1次,但是用在重复的后面表示非贪婪模式
如re.findall('ab+?‘, 'abbbbbb')得到的结果为ab
search
re.search(pattern, string, flags) 根据pattern在string查找一个字串,如果查找到则返回Match object,查找不到则返回None
match
re.match(pattern, string, flags)跟search不同的是,match是从开头匹配的,不是在string内部全部搜索的。
比如:re.match("abc", "bbbabc")是没有匹配结果的,而re.search("abc", "bbabc”)是有匹配结果的。
分组
被()括起来的表达式将作为分组,分组中的|仅在当前分组中有效,分组作为一个整体可以后接量词,比如a(123|456){3}
如果想同时匹配.com和.net的网址,可以使用或运算来执行,如下面代码所示,如果这样写的话正则会默认匹配“|”之前或之后的部分
>>> ptn = re.compile('\w{3,30}\.com|\.net')
>>> re.match(ptn, 'hello.com')
<_sre.SRE_Match object; span=(0, 9), match='hello.com'>
>>> re.match(ptn, 'hello.net') #匹配不到hello.net网址
>>>
如果想匹配 xxx.com 和 xxx.net则需要进行分组
>>> ptn = re.compile('\w{3,30}(\.com|\.net)') #小括号对<span style="font-family: Arial, Helvetica, sans-serif;">(\.com|\.net)进行分组</span>
>>> re.match(ptn, 'hello.net')
<_sre.SRE_Match object; span=(0, 9), match='hello.net'>
>>> re.match(ptn, 'hello.com')
<_sre.SRE_Match object; span=(0, 9), match='hello.com'>
当进行分组时,用finadall会优先返回分组中的值:
>>> ptn = re.compile('\w{3,30}(\.com|\.net)')
>>> re.findall(ptn, 'hello.net')
\<number>
引用标号为<number>的分组匹配到的字符串
>>> ptn = re.compile(r'(\d)abc\1') #\1代表第一个分组(\d)的内容,下面的5abc5可以匹配到,4abc5匹配不到
>>> re.findall(ptn, '5abc5')
['5']
>>> re.findall(ptn, '4abc5')
[]
>>>
(?P<name>...)
parameter <name>这个分组可以通过name来访问分组<pre name="code" class="python">>>> result = re.match("(?P<name>\d{3})", '345')
>>> result.group(0)
'345'
>>> result.group('name')
'345'
(?P=name...)
parameter = name这个分组是用来引用name的分组已经匹配到的字符
>>> result = re.match("(?P<name>\d{3}).(?P=name)", '345a345') #(?P<name>\d{3})匹配到的字符为345,则(?P=name)的值为前面的name匹配到的字符345
>>> result.group()
'345a345'
>>> result = re.match("(?P<name>\d{3}).(?P=name)", '345a789')#根据上面的说明,789是匹配不到的。
>>> result.group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
未分组的括号
(?...)系列的扩展标号中,除了(?P...)之外的所有标号仅作一个辅助表示作用,不会创建一个新组。
(?aiLmsux)
相当于re.A re.I re.L re.M re.S re.U re.X,iLmsux的每个字符代表一个匹配模式,只能用在正则表达式的开头,可选多个。例如下面的忽略大小写的用法:
>>> ptn = re.compile('(?i)hello')
>>> re.findall(ptn, 'hellOH')
['hellO']
(?:...)
(...)的不分组版本,即表示括号内的内容不用做分组,仅用于使用| 和数量词
>>> re.findall('(?:abc){3}', 'abcabcabcabc')
['abcabcabc']#不分组,findall输出全部内容
>>> re.findall('(abc){3}', 'abcabcabcabc')
['abc']#分组的结果,findall优先显示分组内容
>>>
(?#...)
表示注释
(?=...)
xxx(?=...) 之后的字符串内容...需要匹配表达式才能成功匹配。如'a(?=\d)'匹配内容为后面是数字的a
(?!...)
xxx(?=...) 与(?=...)相反,之后的字符串内容...需要不匹配表达式才能成功匹配。如'a(?!\d)'匹配内容为后面不是数字的a
(?<=...)
匹配前面是...的字符串。比如
>>> import re >>> m = re.search('(?<=abc)def', 'abcdef') >>> m.group(0) 'def'
(?<!...)
与(?<...)相反
(?(id/name)yes-pattern|no-pattern)
>>> result = re.match("(\d)xx(?(1)yes-pattern|no-pattern)", "5xxyes-pattern") #?(1) 表示如果有一个分组则执行yes
>>> result.group()
'5xxyes-pattern'
>>> result = re.match("(?P<name>\d)xx(?(name)yes-pattern|no-pattern)", "5xxyes-pattern") #?(name)如果前面有name的分组,则执行yes
>>> result.group()
'5xxyes-pattern'