python正则表达式re模块用法详解

发布时间:2020-02-11编辑:脚本学堂
本文详细介绍了python正则表达式re模块的用法,来自官方文档,加入了作者自己的理解,是学习python正则表达式模块re的好教程,感兴趣的朋友参考下。
python正则表达式re模块用法详解 第二部分的内容。如果正则有圆括号,并且可以匹配到字符串的开始位置时,返回值的第一项,会多出一个空字符串。匹配到字符结尾也是同样的道理:
 

复制代码 代码示例:
>>> re.split('(W+)', '...words, words...')
['', '...', 'words', ', ', 'words', '...', '']

注意,split不会被零长度的正则所分割,例如:
 

复制代码 代码示例:
>>> re.split('x*', 'foo')
['foo']
>>> re.split("(?m)^$", "foonnbarn")
['foonnbarn']

re.findall(pattern, string[, flags])

以列表的形式返回string里匹配pattern的不重叠的子串。string会被从左到右依次扫描,返回的列表也是从左到右一次匹配到的。如果pattern里含有组的话,那么会返回匹配到的组的列表;如果pattern里有多个组,那么各组会先组成一个元组,然后返回值将是一个元组的列表。
由于这个函数不会涉及到MatchObject之类的概念,所以,对新手来说,应该是最好理解也最容易使用的一个函数了。

几个简单的例子:
 

复制代码 代码示例:
#简单的findall
>>> re.findall('w+', 'hello, world!')
['hello', 'world']
#这个返回的就是元组的列表
>>> re.findall('(d+).(d+).(d+).(d+)', 'My IP is 192.168.0.2, and your is 192.168.0.3.')
[('192', '168', '0', '2'), ('192', '168', '0', '3')]
re. finditer(pattern, string[, flags])

和上面的findall()类似,但返回的是MatchObject的实例的迭代器。
还是例子说明问题:
 

复制代码 代码示例:
>>> for m in re.finditer('w+', 'hello, world!'):
... print m.group()
...
hello
world
re.sub(pattern, repl, string[, count])

替换,将string里,匹配pattern的部分,用repl替换掉,最多替换count次(剩余的匹配将不做处理),然后返回替换后的字符串。如果string里没有可以匹配pattern的串,将被原封不动地返回。repl可以是一个字符串,也可以是一个函数(也可以参考我以前的例子)。如果repl是个字符串,则其中的反斜杆会被处理过,比如 n 会被转成换行符,反斜杆加数字会被替换成相应的组,比如 6 表示pattern匹配到的第6个组的内容。
例子:
 

复制代码 代码示例:
>>> re.sub(r'defs+([a-zA-Z_][a-zA-Z_0-9]*)s*(s*):',
...        r'static PyObject*npy_1(void)n{',
...        'def myfunc():')
'static PyObject*npy_myfunc(void)n{'

如果repl是个函数,每次pattern被匹配到时,都会被调用一次,传入一个匹配到的MatchObject对象,需要返回一个字符串,在匹配到的位置,就填入返回的字符串。
例子:
 

复制代码 代码示例:
>>> def dashrepl(matchobj):
...     if matchobj.group(0) == '-': return ' '
...     else: return '-'
>>> re.sub('-{1,2}', dashrepl, 'pro----gram-files')
'pro--gram files'

零长度的匹配也会被替换,比如:
 

复制代码 代码示例:
>>> re.sub('x*', '-', 'abcxxd')
'-a-b-c-d-'

特殊地,在替换字符串里,如果有g这样的写法,将匹配正则的命名组(前面介绍过的,(?P...)这样定义出来的东西)。g这样的写法,也是数字的组,也就是说,g<2>一般和2是等效的,但是万一你要在2后面紧接着写上字面意义的0,你就不能写成20了(因为这代表第20个组),这时候必须写成g<2>0,另外,g<0>代表匹配到的整个子串。
例子:
 

复制代码 代码示例:
>>> re.sub('-(d+)-', '-g<1>0g<0>', 'a-11-b-22-c')
'a-110-11-b-220-22-c'

re.subn(pattern, repl, string[, count])

跟上面的sub()函数一样,只是它返回的是一个元组 (新字符串, 匹配到的次数)
,还是用例子说话:
 

复制代码 代码示例:
>>> re.subn('-(d+)-', '-g<1>0g<0>', 'a-11-b-22-c')
('a-110-11-b-220-22-c', 2)

re.escape(string)
把string中,除了字母和数字以外的字符,都加上反斜杆。
 

复制代码 代码示例:
>>> print re.escape('abc123_@#$')
abc123_@#$

exception re.error

如果字符串不能被成功编译成正则表达式或者正则表达式在匹配过程中出错了,都会抛出此异常。但是如果正则表达式没有匹配到任何文本,是不会抛出这个异常的。
正则对象
正则对象由re.compile()返回。它有如下的属性和方法。
match(string[, pos[, endpos]])

作用和模块的match()函数类似,区别就是后面两个参数。
pos是开始搜索的位置,默认为0。endpos是搜索的结束位置,如果endpos比pos还小的话,结果肯定是空的。也就是说只有pos 到 endpos-1 位置的字符串将会被搜索。
例子:
 

复制代码 代码示例:
>>> pattern = re.compile("o")
>>> pattern.match("dog")      # 开始位置不是o,所以不匹配
>>> pattern.match("dog", 1)   # 第二个字符是o,所以匹配
<_sre.SRE_Match object at ...>
 

search(string[, pos[, endpos]])

作用和模块的search()函数类似,pos和endpos参数和上面的match()函数类似。
 

split(string[, maxsplit=0])
findall(string[, pos[, endpos]])
finditer(string[, pos[, endpos]])
sub(repl, string[, count=0])
subn(repl, string[, count=0])

这几个函数,都和模块的相应函数一致。
flags
编译本RE时,指定的标志位,如果未指定任何标志位,则为0。
 

复制代码 代码示例:
>>> pattern = re.compile("o", re.S|re.U)
>>> pattern.flags
48
 

groups
RE所含有的组的个数。
groupindex

一个字典,定义了命名组的名字和序号之间的关系。
例子:这个正则有3个组,如果匹配到,第一个叫区号,最后一个叫分机号,中间的那个未命名
 

复制代码 代码示例:
>>> pattern = re.compile("(?P<quhao>d+)-(d+)-(?P<fenjihao>d+)")
>>> pattern.groups
3
>>> pattern.groupindex
{'fenjihao': 3, 'quhao': 1}
 

pattern

建立本RE的原始字符串,相当于源代码了,呵呵。
还是上面这个正则,可以看到,会原样返回:
>>> print pattern.pattern
(?P<quhao>d+)-(d+)-(?P<fenjihao>d+)
Match对象
re.MatchObject被用于布尔判断时,始终返回True,所以你用 if 语句来判断某个 match() 是否成功是安全的。
它有以下方法和属性:
expand(template)

用template做为模板,将MatchObject展开,就像sub()里的行为一样,看例子:
 

复制代码 代码示例:
>>> m = re.match('a=(d+)', 'a=100')
>>> m.expand('above a is g<1>')
'above a is 100'
>>> m.expand(r'above a is 1')
'above a is 100'

group([group1, ...])

返回一个或多个子组。如果参数为一个,就返回一个子串;如果参数有多个,就返回多个子串注册的元组。如果不传任何参数,效果和传入一个0一样,将返回整个匹配。如果某个groupN未匹配到,相应位置会返回None。如果某个groupN是负数或者大于group的总数,则会抛出IndexError异常。
>>> m = re.match(r"(w+) (w+)", "Isaac Newton, physicist")
>>> m.group(0)       # 整个匹配
'Isaac Newton'
>>> m.group(1)       # 第一个子串
'Isaac'
>>> m.group(2)       # 第二个子串
'Newton'
>>> m.group(1, 2)    # 多个子串组成的元组
('Isaac', 'Newton')
如果有其中有用(?P...)这种语法命名过的子串的话,相应的groupN也可以是名字字符串。例如:
 

复制代码 代码示例:
>>> m = re.match(r"(?P<first_name>w+) (?P<last_name>w+)", "Malcolm Reynolds")
>>> m.group('first_name')
'Malcolm'
>>> m.group('last_name')
'Reynolds'

如果某个组被匹配到多次,那么只有最后一次的数据,可以被提取到:
 

复制代码 代码示例:
>>> m = re.match(r"(..)+", "a1b2c3")  # 匹配到3次
>>> m.group(1)                        # 返回的是最后一次
'c3'

groups([default])

返回一个由所有匹配到的子串组成的元组。default参数,用于给那些没有匹配到的组做默认值,它的默认值是None
例如:
 

复制代码 代码示例:
>>> m = re.match(r"(d+).(d+)", "24.1632")
>>> m.groups()
('24', '1632')

default的作用:
 

复制代码 代码示例:
>>> m = re.match(r"(d+).?(d+)?", "24")
>>> m.groups()      # 第二个默认是None
('24', None)
>>> m.groups('0')   # 现在默认是0了
('24', '0')
 

groupdict([default])

返回一个包含所有命名组的名字和子串的字典,default参数,用于给那些没有匹配到的组做默认值,它的默认值是None,例如:
 

复制代码 代码示例:
>>> m = re.match(r"(?P<first_name>w+) (?P<last_name>w+)", "Malcolm Reynolds")
>>> m.groupdict()
{'first_name': 'Malcolm', 'last_name': 'Reynolds'}

start([group])
end([group])
返回的是:被组group匹配到的子串在原字符串中的位置。如果不指定group或group指定为0,则代表整个匹配。如果group未匹配到,则返回 -1。
对于指定的m和g,m.group(g)和m.string[m.start(g):m.end(g)]等效。
注意:如果group匹配到空字符串,m.start(group)和m.end(group)将相等。
例如:
 

复制代码 代码示例:
>>> m = re.search('b(c?)', 'cba')
>>> m.start(0)
1
>>> m.end(0)
2
>>> m.start(1)
2
>>> m.end(1)
2

下面是一个把email地址里的“remove_this”去掉的例子:
 

复制代码 代码示例:
>>> email = "tony@tiremove_thisger.net"
>>> m = re.search("remove_this", email)
>>> email[:m.start()] + email[m.end():]
'tony@tiger.net'
 

span([group])
返回一个元组: (m.start(group), m.end(group))
pos
就是传给RE对象的search()或match()方法的参数pos,代表RE开始搜索字符串的位置。
endpos
就是传给RE对象的search()或match()方法的参数endpos,代表RE搜索字符串的结束位置。
lastindex
最后一次匹配到的组的数字序号,如果没有匹配到,将得到None。
例如:(a)b、((a)(b))和((ab))正则去匹配'ab'的话,得到的lastindex为1。而用(a)(b)去匹配'ab'的话,得到的lastindex为2。
lastgroup
最后一次匹配到的组的名字,如果没有匹配到或者最后的组没有名字,将得到None。
re
得到本Match对象的正则表达式对象,也就是执行search()或match()的对象。
string
传给search()或match()的字符串。

原文参考:https://docs.python.org/2/library/re.html