python之正则表达式
Posted `关关雎鸠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python之正则表达式相关的知识,希望对你有一定的参考价值。
1. 正则表达式—特殊表达式含义
(1)普通字符集
1) w 匹配字母数字及下划线
2) W 匹配非字母数字及下划线
3) s 匹配任意空白字符,等价于 [ f].
4) S 匹配任意非空白字符
5) d 匹配任意数字,等价于 [0-9]
6) D 匹配任意非数字
7) 1...9 匹配第n个分组的内容。
8) [a-zA-Z0-9] 匹配任何字母及数字
(2)数量字符集(用在字符或分组符(...)之后,非贪婪匹配*? +?)
1) (点). 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,可以匹配包括换行符的任意字符
2) * 匹配前一个字符0次1次或多次
3) + 匹配前一个字符1次或多次
4) ? 匹配前一个字符0次或1次
5) {m} 匹配前一个字符m次
6) {m,n} 匹配前一个字符m到n次
7) {m,} 匹配前一个字符至少m次
8) {,n} 匹配前一个字符0到n次,最多n次
(3)边界匹配符
1) ^(托字符) 匹配字符串开头,如果是多行则匹配每一行的开头
2) [^] 在[...]中,^表示否定,如非字母[^a-zA-Z],非数字[^0-9]
3) $ 匹配字符串或一行的结尾,如果是多行匹配模式,则每一行的结尾
4) A 仅匹配字符串的开始,同^
5) 匹配一个单词的边界,也就是指单词和空格间的位置
6) B [^],表示匹配非单词边界
7) 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。
8) z 匹配字符串结束
(4)逻辑匹配符
1) |(或)
匹配 | 左右任意一种正则表达式,如果左边表达式匹配上,匹配结束,不再匹配右边的正则表达式,该符号一般放在()中使用,如果没在圆括号中则它的范围是整个正则表达式
2) 分组 (...)
后向引用,用()括起来的正则表达式将被作为一个分组,从正则表达式的左边依次算起,有多少个左括号‘(‘,就有 多少个分组,分组的编码从1依次加1,无论是括号中嵌套括号,并且分组表达式作为一个整体,后可接数量词。
3) <number>
引用分组匹配到的分组编号为<number>的字符串 如:1...9
4) (?P<name>...)
命名分组,除了默认的分组编号外再指定一个别名分组
注意:P是大写
5) (?P=name)
引用别名为name的分组匹配,这个是在正则表达式中引用,表示匹配重复的字符串,也可以使用编号引用。
注意:P是大写
(5)特殊匹配符
1) (?imx) 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
2) (?-imx) 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
3) (?:...) 匹配到的括号内字符串不作为分组
4) (?!pattern) 前向否定断言语法,表示否定开头
只能用在正则表达式的开头,pattern是匹配模式,它后面的内容需要不匹配 该正则表达式才匹配成功
5) (?<!pattern) 后向否定断言语法,表示否定结尾
前面的内容需要不匹配该pattern模式才匹配成功
6) (?=pattern) 前向肯定断言语法.
需要匹配pattren模式才能匹配成功,表示肯定前面的字符内容
7) (?<=pattern) 后向肯定断言语法
需要匹配pattern模式才能匹配成功,表示肯定后面的字符内容
9) (?#...) #后面的内容将被作为注释而忽略
2. 正则表达式-个别注意点(原字符串r、反斜杠、^、$、^$)
(1)使用原字符串r
由于正则表达式通常包含反斜杠等特殊字符,所以我们最好使用原始字符串来表 示他们。如:r’d’,等价于’\d’,表示匹配一个数字。
如果不使用原始字符,转译时常需要两个:
(1)通过解释器转译 (2)通过re模块转译
(2)转译反斜杠
正则表达式匹配反斜杠时,正则表达式字符串和待匹配字符串都要双斜杠\
>>> print ‘\‘
>>> print re.match(r‘\‘,‘\‘).group()
(3)^和A,$和,^…$
^(也可以用A)必须在开头匹配(字符串开头,非单词开头),等价于match
re.search(r‘^abc‘,‘ abc‘)
$(也可以用)必须在结尾匹配(字符串结尾,非单词结尾)
re.search(r‘^abc$‘,‘abc‘)
‘^abc$‘ 表示字符串中间除了abc不能有其他字符
开头结尾都是abc,中间任意字符
>>> re.search(r‘^abc.*abc$‘ , ‘abcfadsfas_ [email protected]*&abc‘)
<_sre.SRE_Match object at 0x0000000003659440>
3. 编译正则表达式-- re.compile
使用re的一般步骤是先将正则表达式的字符串形 式编译为pattern实例,然后使用pattern实例处理文本并获取匹配结果(一个Match实例(值为True)),最后使用Match实例获取信息,进行其他的操作。
可以把那些经常使用的正则表达式编译成正则表达式对象,可以提高程序的执行速度。
一处编译,多出复用
re.compile(pattern, flags=0)
第二个参数flag是匹配模式,取值可以使用按位或运算符“|”表示同时生效,
比如re.I | re.M。当然你也可 以在regex字符串中指定模式,以下两种写法等价
re.compile(‘pattern‘, re.I | re.M)
re.compile(‘(?im)pattern‘)
4. pattern对象属性及方法
Pattern对象是一个编译好的正则表达式,也就是通过re.compile()函数编译后得到结果。
通过pattern提供的一系列方法可以对文本进行匹配查找
pattern提供了几个可读属性及方法用于处理正则表达式
(1)flags属性
该属性表示获取编译时用的匹配模式,数字形式,指定匹配模式时也可以输入数字
如:re.compile(r‘w+‘, 16)
通过pattern.flags我们可以查看编译时的选 项,不过它显示的不是’S’,而是一个数值16。其实re.S是一个整数,16就是 它的值。如果是I,则显示数值为。
re.S = re.DOTALL = 16
pattern = re.compile(r‘w+‘, re.DOTALL)
print pattern.flags
>>>16
(2)groups属性
该属性表示获取表达式中分组的数量。
(3)groupindex属性
以表达式中有别名的组的别名为键、以该组对应的编号为值的字典,没有别名的组不包含在内
p = re.compile(r‘(w+)(?P<sign>.*)‘, re.DOTALL)
print p.groupindex
>>>{‘sign‘: 2}
5. match方法
(1)pattern.match方法
这个方法将在字符串string的pos位置开始 尝试匹配pattern,如 果pattern匹配成功,无论是否达到结束位 置endpos,都会返回一个匹配成功后的 Match对象(值为True);
如果匹配不成功,或者 pattern未匹配结束就达到endpos,则返回 None
(2)re.match方法
该函数的作用是尝试从字符串 string的起始位置开始匹配一个 模式pattern,如果匹配成功返 回一个匹配成功后的Match对象, 否则返回None
(3) re.match和pattern.match区别
re.match方法与pattern.match()方法 区别在于,它不能指定匹配的区 间pos和endpos两个参数
6. search方法
(1)pattern. search方法
该方法的作用是在string[pos, endpos]区间从pos下标处开始匹配pattern,如果匹配成功, 返回匹配成功的Match对象(值为True);
如果没有匹配成功,则将pos加1后重新尝试匹配,直到 pos=endpos时仍无法匹配则返回None
(2)re. search方法
扫描整个字符串并返回第一次成功的匹配对象,如果匹配失败,则返回None。
该方法与pattern.search()方法区别在于,它不能指定匹配的区间pos和endpos两个参数
re.match与re.search的区别
re.match与re.search的区别在于,re.match只 匹配字符串的开始,如果字符串开始不符合正则表达式, 则匹配失败,并返货None;而re.search匹配整个字符串, 直到找到一个匹配
7. findall方法
相比其他方法,findall方法有些特殊。它的作用是查找字符串中所有能匹配的字符串,并以结 果存于列表中,然后返回该列表
注意:当有括号(分组)时,列表中的字符串只是圆括号中的内容,不是整个正则表达式所匹配的内容
(1)pattern.findall方法
该方法的作用是在string[pos, endpos]区间从pos下标处开始查找所有满足pattern的子串, 直到endpos位置结束,并以列表的形式返回查找的结果,如果未找到则返回一个空列表。
(2)re.findall
获取字符串中所有能匹配的字符串,并以列表的形式返回。
1) 当正则表达式中含有多个圆括号()时
返回列表中的元素由所有满足匹配的内容组成,但是每个元素都是由表达式中所有圆括号匹配的内容组成的元组
>>> re.findall(r‘a(b)(c)‘,‘abcabc‘)
[(‘b‘, ‘c‘), (‘b‘, ‘c‘)]
2) 当正则表达式中只带有一个圆括号时
返回的列表的元素由所有能成功匹配表达式中圆括
号匹配的内容组成,并且该列表中的元素都是字符串
>>> re.findall(r‘a(b)c‘,‘abcabc‘)
[‘b‘, ‘b‘]
3) 当正则表达式中没有圆括号时
返回列表中的元素由所有能成功匹配的子串组成。
>>> re.findall(r‘abc‘,‘abcabc‘)
[‘abc‘, ‘abc‘]
(3)finditer方法
finditer函数跟findall函数类似,但返回的是一个迭代器, 而不是一个像findall函数那样的存有所有结果的list。
而且finditer的每一个对象可以使用group(可以获取整个匹配串)和groups方法,如果有分组,findall只能获得分组,不能获得整个匹配串
>>> re.findall(r‘a(b)(c)‘,‘abcd 12abcde‘)
[(‘b‘, ‘c‘), (‘b‘, ‘c‘)]
>>> a = re.finditer(r‘a(b)(c)‘,‘abcd 12abcde‘)
>>> for i in a :
... print i.group()
...
abc
abc
>>> a = re.finditer(r‘a(b)(c)‘,‘abcd 12abcde‘)
>>> for i in a:
... print i.groups()
...
(‘b‘, ‘c‘)
(‘b‘, ‘c‘)
8. re.split(pattern, string[, maxsplit=0, flags=0])
>>>import re
>>> re.split(‘W+‘, ‘runoob, runoob, runoob.‘)
[‘runoob‘, ‘runoob‘, ‘runoob‘, ‘‘]
(1)以分组为分割符的时候,分组内容也会被保存下来
>>> re.split(‘(W+)‘, ‘ runoob, runoob, runoob.‘)
[‘‘, ‘ ‘, ‘runoob‘, ‘, ‘, ‘runoob‘, ‘, ‘, ‘runoob‘, ‘.‘, ‘‘]
>>> re.split(‘W+‘, ‘ runoob, runoob, runoob.‘, 1)
[‘‘, ‘runoob, runoob, runoob.‘]
(2)可同时使用多个分隔符,分隔符,和.都会被切割
>>> re.split(‘[,.]‘,r‘hello,Tom.how are you‘)
[‘hello‘, ‘Tom‘, ‘how are you‘]
(3)对于一个找不到匹配的字符串而言,split 不会对其作出分割
>>> re.split(‘a*‘, ‘hello world‘)
[‘hello world‘]
9. sub方法
(1)pattern.sub(repl, string[, count = 0])
1) 当repl是一个字符串
可以使用id或g<id>、g<name>引用分组,但不能使用编号0。
2) 当repl是一个方法
它必须传一个Match对象,并必须返回一个字符串用于替换(返回的字符串中不能再引用分组)。
str.title() 将字符串第一个字符转换成大写
>>> ‘abc‘.title()
‘Abc‘
(2)subn方法
这个函数跟sub函数用法差不多,只是它有一个额外的特征,结果是返回一个tuple,tuple第 一个元素是替换后的新字符串,第二个元素是替换的次数。
import re
def add(m):
v = int(m.group(0))
return str(v + 1)
p = re.compile("(d+)")
result = p.subn(add, "1 2 3 4 5")
print result
>>>(‘2 3 4 5 6‘, 5)
10. re.escape方法
可以将字符串中所有可能被解释为正则运算符的字符进行转译。
>>> re.escape(‘www.python.org‘)
‘www\.python\.org‘
11. Match对象的属性
(1)string 属性:
获取匹配时使用的字符串对象
>>> m = re.match(r‘d+‘,‘456abc‘)
>>> m.string
‘456abc‘
(2)re 属性:
匹配时使用的pattern对象,也就是匹配到内容的正则表达 式对象
>>> m
<_sre.SRE_Match object at 0x02C8FA68>
>>> m.re
<_sre.SRE_Pattern object at 0x02D4ECD0>
(3)pos属性:
该属性表示文本中正则表达式开始搜索的索引。值与Pattern.match()和Pattern.seach()方法中的同名参数相同
>>> m.pos
0
(4)endpos属性:
该属性表示文本中正则表达式结束搜索的索引。值与Pattern.match()和 Pattern.seach()方法中的同名参数相同
>>> m.endpos
6
(5)lastindex属性:
该属性表示最后一个被捕获的分组在文本中的索引。如果没有被捕获的分组,将为None
>>> m = re.match(r‘a(b)(c)d‘,‘abcdef‘)
>>> m.lastindex
2
(6)lastgroup属性:
该属性表示最后一个被捕获的分组别名。如果这个分 组没有别名或者没有被捕获的分组,将为None。
(7)group([group1, ...]):
获得一个或多个分组截获的字符串;指定多个参数时将以元组形式返回。group1可以使用编 号也可以使用别名;编号0代表匹配的整个子串;默认返回group(0)
group函数传多个参数
p = re.compile(‘(a(b)c)d‘)
m = p.match(‘abcd‘)
resTup = m.group(1,2,1)
print resTup
>>>(‘abc‘, ‘b‘, ‘abc‘)
(8)groups([default=None])
以元组形式返回全部分组截获的字符串。相当于调用group(1,2,…last)
(9)start([group=0])
返回指定的组截获的子串在string中的起始索引(子串第一个字符的索引)。默认为第0组,即整个字符串
(10)end([group=0])
返回指定的组截获的子串在string中的结束索引(子串最后一个字符的索引)。group默认值 为0,即整个字符串
(11)span([group])
该方法表示以元组的形式返回 (start(group), end(group)),即某个分组的匹配文字内容在被 匹配字符串的开始索引位置和结束索引位置
(12)expand(template)
将匹配到的分组代入template中然后返回。template中可以使用id或g<id>、g<name> 引用分组,但不能使用编号0。id与g<id>是等价的;但10将被认为是第10个分组,如果 你想表达1之后是字符‘0‘,只能使用g<1>0。
m = re.search(r‘(w+)! (w+) (w+)‘,‘HMan! How finny!‘) #将匹配的结果带入 print m.expand(r‘resut:3 2 1‘)
>>> resut:finny How HMan
(13)groupdict([default=None])
该函数的作用是,将所有匹配到并且指定了别名的分组,以别名为key,匹配到的字串为value, 存于字典中,然后返回这个字典。如果表达式中未设置别名分组,就会返回一个空字典
>>> m = re.search(r‘(?P<num>d+)(w+)‘,‘78fd‘)
>>> m.groupdict()
{‘num‘: ‘78‘}
12. 正则表达式--正则的贪婪性(.*)
“.*” 在匹配的过程中会回溯,先匹配0次, 如果整个表达式能匹配成功,再匹配一次,如果还是能匹配,那就匹配 两次,这样一次次试下去,直到不能匹配成功时,返回最近一次匹配成 功的结果,这就是”.*”的贪婪性
在点星(.*)后面加一个问号(?),表示匹配前面匹配的字符串0次或1次,这样我们就可以 将点星(.*)的贪婪性暂时屏蔽
13. 正则表达式—修饰符
正则表达式可以包含一些可选标志修饰符来控制匹配模式,用在正则表达式处理函数中的flag参数中
(1) |多个标志同时生效
可以通过使用按位或运算符“|“来指定 它们,表示同时生效。
如: re.I | re.M被设置成I和M标志,
(2) re.I 全写(re.IGNORECASE)
表示使匹配时,忽略大小
(3) re.M 全写(re.MULTILINE)
多行匹配,影响 ^ 和 $的行为
(4) re.S 全写(re.DOTALL)
使点(.)匹配包括换行在内的所有字符
(5) re.X 全写(re.VERBOSE)
这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。
14. 无名/有名分组
(1) 正则表达式—无名分组
从正则表 达式的左边开始看,看到的第一个左括号“(”表示表示第一个分组,第二个表示第二个分组, 一次类推。
需要注意的是,有一个隐含的全局分组(就是索引号为0的分组),就是整个正则 表达式匹配的结果
(2) 正则表达式—有名分组
命名分组就是给具体有默认分组编号的组另外再起一个别名,方便以后的引用。 命令分组的语法格式如下: (?P<name>正则表达式)
语法格式中的字符P必须是大写的“P”,name是一个合法的标识符,表示分组的别名。
s = "ip=‘230.192.168.78‘,version=‘1.0.0‘"
res = re.search(r"ip=‘(?P<ip>d+.d+.d+.d+).*", s)
print res.group(‘ip‘)#通过命名分组引用分组
15. 正则表达式—后向引用
当用“()”定义了一个正则表达式分组后,正则引擎就会把匹配的组按照顺序进行编号,然后存 入缓存中。这样我们就可以在后面对已经匹配过的内容进行引用,这就叫后向引用。
(1)通过索引引用
数字 1表示引用第一个分组,2引用第二个分组,以此类推, 引用第n个组,而 则表示引用整个 被匹配的正则表达式本身。
交换字符串的位置
import re
s = ‘abc.xyz‘ # 交换.号两边的字符串
res = re.sub(r‘(.*).(.*)‘, r‘2.1‘, s)
print res
>>>xyz.abc
(2) (?P=name)通过命名分组名进行引用
(?P=name) 字符P必须是大写的P,name表示命名分组的分组名
(?P<name>)(?P=name) 引用分组的值匹配值必须与第一个分组匹配值相等才能匹配到
例如:
1) 引用前一个分组,前后值相同都是2,故能匹配到
>>> re.match(r‘(?P<xst>d)(?P=xst)‘,‘22‘).groups()
(‘2‘,)
>>> re.match(r‘(?P<xst>d)(?P=xst)‘,‘22‘).group()
‘22‘
2) 引用前一个分组,前后值不相同分别为2和3,故不能匹配到
>>> re.match(r‘(?P<xst>d)(?P=xst)‘,‘23‘).group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: ‘NoneType‘ object has no attribute ‘group‘
16. 正则表达式—前后向断言
(1) 前向肯定断言与后向肯定断言
1) 前向肯定断言的语法:
(?<=pattern) 前向肯定断言表示你希望匹配的字符串前面是pattern匹配的内容时,才匹配。
2) 后向肯定断言的语法:
(?=pattern) 后向肯定断言表示你希望匹配的字符串的后面是pattern匹配的内容时,才匹配
3)前后向断言同时使用
如果在一次匹配过程中,需要同时用到前向肯定断言和后向肯定断 言时,那你必须将前向肯定断言表达式写在要匹配的正则表达式的前面,而后向肯定断言表 达式写在你要匹配的字符串的后面
(2) 前向否定断言与后向否定断言
1) 前向否定断言的语法:
(?<!pattern) 前向否定断言表示你希望匹配的字符串的前面不是pattern匹配的内容时,才匹配.
2) 后向否定断言的语法:
(?!pattern) 后向否定断言表示你希望匹配的字符串后面不是pattern匹配的内容时,才匹配。
(3)注意
前向肯定(否定)断言括号中的正则表达式必须是能确定长度的正则表达式,比如w{3},而不能写成 w*或者w+或者w?等这种不能确定个数的正则模式符。
以上是关于python之正则表达式的主要内容,如果未能解决你的问题,请参考以下文章