本文主要介绍了python中re模块的7个函数,根据一些实例辅助对于正则表达式的理解。
本文例子主要来源于下面的详细教程,例子基本都根据自己的理解有所改动和解释。
详细教程:http://www.runoob.com/python/python-reg-expressions.html
还有一篇详细的总结值得参考:https://www.cnblogs.com/greatfish/p/7572131.html
关于正则表达式的入门介绍:https://www.jb51.net/tools/zhengze.html
菜鸟教程中方便的正则表达式在线测试,底下有表达式示例:https://c.runoob.com/front-end/854
re.match(pattern, string, flags=0)
import re
print(re.match('www', 'www.123.com').span()) #从起始位置匹配
print(re.match('com', 'www.123.com')) #没有从起始位置匹配
re.match()有从起始位置开始匹配的特性。
以上的返回结果为:
(0, 3) #表示从0个字符开始到第2个字符匹配
None
如果不加.span()
返回结果为:
<_sre.SRE_Match object; span=(0, 3), match='www'>
group
方法import re
line = "His cats are smarter than her dogs"
matchObj = re.match(r'(.*) are (.*?) .*', line, re.M|re.I)
if matchObj:
print ("matchObj.groups(): ", matchObj.groups()) #返回一个包含所有小组字符串的元组
print ("matchObj.group(): ", matchObj.group()) #返回匹配的整个表达式的字符串
print ("matchObj.group(1): ", matchObj.group(1)) #返回特定组匹配的字符串
print ("matchObj.group(2): ", matchObj.group(2))
print ("matchObj.group(3): ", matchObj.group(3))
r
表示字符串为非转义的原始字符串,让编译器忽略转义字符,也就是反斜杠。这句话中没有反斜杠,所以r可有可无。
句子中一共有两组,每个括号代表一组,所以打印matchObj.group(3)
第三组的时候会报错。
(.*)
为第一个分组,其中.*
匹配除换行符的所有字符。
(.*?)
为第二个分组,其中?
表示非贪婪模式,只匹配符合条件的最少字符。所以在结果中只取了一个单词。
最后的.*
由于没有括号,所以并不是分组,不计入匹配结果中。
matchObj.group()
与matchObj.group(0)
意义相同。
在本例中matchObj.groups()
与matchObj.group(1, 2)
结果相同。
可选标识符:
正则表达式可以包含一些可选标志修饰符来控制匹配的模式。多个标志可以通过|
来指定。
其中re.I
使匹配对大小写不敏感,re.M
表示多行匹配,影响^
和$
。
以上前4个返回结果为:
matchObj.groups(): ('His cats', 'smarter')
matchObj.group(): His cats are smarter than her dogs
matchObj.group(1): His cats
matchObj.group(2): smarter
最后一个报错no such group
re.search(pattern, string, flags=0)
import re
print(re.search('www', 'www.123.com').span())
print(re.search('com', 'www.123.com.com').span())
返回结果为:
(0, 3)
(8, 11)
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败。而re.search匹配整个字符串,直到找到第一个匹配。
re.sub(pattern, repl, string, count=0, flags=0)
repl
替换的字符串,也可以为一个函数。
string
要被替换的字符串。
count
模式匹配后替换的最大次数。默认0表示替换所有的匹配。
import re
phone = "2004-959-559 # This is an foreign phone number."
# 删除字符串中的注释
num = re.sub(r'#.*$', "", phone)
print("Phone NO is: ", num)
# 删除非数字的字符,包括'-'和注释
num = re.sub(r'\D', "", phone)
print("Phone NO is: ", num)
#.*$
表示匹配#好后面所有内容,一直到字符串结束为止。
\D
表示匹配所有的非数字字符。
返回结果为:
Phone NO is: 2004-959-559
Phone NO is: 2004959559
import re
def double(matched):
value = int(matched.group('value'))
return str(value*2)
s = "AH343I3U-4H97K0-J-"
print(re.sub(r'(?P\d+)' , double, s))
(?P
可以为组起一个别名,便于后续引用。
\d
表示匹配所有的数字字符。
+
表示匹配一次或多次。
返回结果:
AH686I6U-8H194K0-J-
re.compile(pattern, flags)
用于生成正则表达式对象,供re.search()和re.match()等其它函数使用。
import re
pattern = re.compile(r'\d+')
print(pattern.match('one12two3three'))
print(pattern.match('one12two3three', 2))
print(pattern.match('one12two3three', 3).span())
m = pattern.match('one12two3three', 3, 4)
print(m.group())
print(m.start())
print(m.end())
使用pattern.match()
方法,可以选定匹配的起始以及结束位置。
之前是通过re.match()
函数生成对象,对象可以调用group()
方法。
现在是通过re.compile()
函数生成正则表达式对象后,通过调用match()
方法再生成类似上面的对象。不用多次输入相同的正则表达式值,更简练也更具有灵活性。
另外m.start()
和m.end()
可以返回匹配字符串的起始位置和结束位置。
返回结果为:
None
None
(3, 5)
1
3
4
import re
pattern = re.compile('([a-z]+) ([a-z]+)', re.I)
s = "Hello World4 Wide Web"
m = pattern.match(s)
print(m.groups())
print(m.group(1))
([a-z]+) ([a-z]+)
表示匹配 纯字母字符串+空格+纯字母字符串,其中纯字母字符串至少包含一个字符。
返回结果为:
('Hello', 'World')
Hello
findall(string[, pos[, endpos]])
import re
pattern = re.compile(r'\d+', re.I)
s = "happy123hhh 456z3 4"
print(pattern.findall(s))
返回结果:
['123', '456', '3', '4']
在字符串中找到所有匹配的字符串,并把它们作为一个迭代器返回。
import re
pattern = re.compile(r'\d+', re.I)
s = "happy123hhh 456z3 4"
m = pattern.finditer(s)
print(m)
for match in m:
print(match, ' ', match.group())
最后match.group()
返回整个匹配上的字符串。
返回结果:
object at 0x0000018EF0E88CF8>
<_sre.SRE_Match object; span=(5, 8), match='123'> 123
<_sre.SRE_Match object; span=(12, 15), match='456'> 456
<_sre.SRE_Match object; span=(16, 17), match='3'> 3
<_sre.SRE_Match object; span=(18, 19), match='4'> 4
re.split(pattern, string[, maxsplit=0[, flags=0]])
import re
s = 'happy, happy, happy.'
print(re.split(r'\W+', s))
print(re.split(r'\W+', s, 1))
print(re.split(r'(\W+)', s))
print(re.split(r'\d+', s, 1))
其中\W
表示非字母字符。
返回结果为:
['happy', 'happy', 'happy', '']
['happy', 'happy, happy.']
['happy', ', ', 'happy', ', ', 'happy', '.', '']
['happy, happy, happy.']
第一个结果中,''
的出现是由于.
将字符串分成了happy
和空。
第二个结果,是因为只分割了一次。
第三个结果是字符串完全分割后得到的列表。
如果找不到匹配的字符串,字符串不会被分割。