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之正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

Python系列之正则表达式

python 之正则表达式

python之正则表达式

python之(re)正则表达式上

Python之正则表达式

正则表达式之Python编程