彩虹然

rainbow-ran

Python3.7之re正则表达式

正则表达式(Regular Expression)用于描述一种字符串匹配的模式,它可用于检查一个字符串是否含有某个子串,也可用于从字符串中提取匹配的子串,或者对字符串中匹配的子串执行替换操作。

这个模块提供了与 Perl 语言类似的正则表达式匹配操作。

一、修饰符/Flags标志符

re.I(re.IGNORECASE): 忽略大小写
re.M(MULTILINE): 多行模式,改变‘^’和’$’的行为
re.S(DOTALL): 使'.'匹配包括换行在内的所有字符
re.X(re.VERBOSE) 可以给你的表达式写注释,使其更可读

二、模式

1.单字符匹配规则

'.' 默认匹配除\n之外的任意一个字符,若指定flag DOTALL或S,则匹配任意字符,包括换行

res = re.search('.', 'abcd')
res2 = re.search('.', '\nabcd', re.DOTALL)
print(res)
print(res2)
'''
<re.Match object; span=(0, 1), match='a'>
<re.Match object; span=(0, 1), match='\n'>
'''

[] 匹配[]中列举的字符

res = re.search('[0-9]', 'lkso092')
print(res)
'''
<re.Match object; span=(4, 5), match='0'>
'''

'\A' 只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的,相当于re.match('abc',"alexabc") 或^

res = re.search('\Aabc', 'vivianabc')
res1 = re.search('^abc', 'abcvivian')
res2 = re.match('abc', 'abcvivian')
print(res)
print(res1)
print(res2)
'''
None
<re.Match object; span=(0, 3), match='abc'>
<re.Match object; span=(0, 3), match='abc'>
'''

'\Z' 匹配字符结尾,同$

res = re.search('ac\Z', 'abcacac')
print(res)
'''
<re.Match object; span=(5, 7), match='ac'>
'''

'\d' 匹配数字0-9

res = re.search('\d', 'kji980')
print(res)
'''
<re.Match object; span=(3, 4), match='9'>
'''

'\D' 匹配非数字

'\w' 匹配[A-Za-z0-9]

'\W' 匹配非[A-Za-z0-9]

2.表示数量的规则

'* ' 对它前面的正则式匹配0到任意次重复, 尽量多的匹配字符串。 ab* 会匹配 'a', 'ab', 或者 'a'后面跟随任意个'b'。 re.search('a*','aaaabac') 结果'aaaa';

'+' 对它前面的正则式匹配1到任意次重复,ab+ 会匹配 'a' 后面跟随1个以上到任意个 'b',它不会匹配 'a'。re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']

'?' 对它前面的正则式匹配0到1次重复。 ab? 会匹配 'a' 或者 'ab' 。re.search('b?','alex').group() 匹配b 0次
'{m}' 对其之前的正则式指定匹配 m 个重复;少于 m 的话就会导致匹配失败。比如,a{6} 将匹配6个 'a' , 但是不能是5个 。re.search('b{3}','alexbbbs').group() 匹配到'bbb'

'{m,n}' 对正则式进行 m 到 n 次匹配,在 m 和 n 之间取尽量多。 比如,a{3,5} 将匹配 3 到 5个 'a'。忽略 m 意为指定下界为0,忽略 n 指定上界为无限次。 比如 a{4,}b 将匹配 'aaaab' 或者1000个 'a' 尾随一个 'b',但不能匹配 'aaab'。逗号不能省略,否则无法辨别修饰符应该忽略哪个边界。re.findall("ab{1,3}","abb abc abbcbbb") 结果['abb', 'ab', 'abb']

3.其他规则

'^' 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)

'$' 匹配字符串尾或者换行符的前一个字符,在 MULTILINE 模式匹配换行符的前一个字符。在 'foo1\nfoo2\n' 搜索 foo.$ ,通常匹配 'foo2' ,但在 MULTILINE 模式 ,可以匹配到 'foo1' 。即若指定flags MULTILINE ,re.search('foo.$','foo1\nfoo2\n',re.MULTILINE).group() 会匹配到foo1

'|' 匹配|左或|右的正则表达式,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'

'(...)' 分组匹配, re.search("(abc){2}a(123|45)", "abcabca456c").group() 结果为'abcabca45'

's' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'

'(?P...)' 分组匹配 (?P) :分组起别名 ,(?P=name):引用别名为name分组匹配到的字符串

res1 = re.search(r'(?P<group1>\d{3})(?P<group2>[a-z]{3})(?P<group3>[A-Z]{3})', '123123aksEDWDSX')
res2 = re.search(r'(?P<group1>\d{3})(?P<group2>[a-z]{3})(?P<group3>[A-Z]{3})', '123123aaaaksEDWDSX')
print(res1.groupdict())
# {'group1': '123', 'group2': 'aks', 'group3': 'EDW'}
print(res2.groupdict())
# AttributeError: 'NoneType' object has no attribute 'groupdict'

三、模块对象

re.match()

re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

函数语法:

re.match(pattern, string, flags=0)

函数参数说明:

参数 描述
pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

匹配成功re.match方法返回一个匹配的对象,否则返回None。

我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。

m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
print(m.group(0))
print(m.group(1))
print(m.group(2))
print(m.groups())

# 010-12345
# 010
# 12345
# ('010', '12345')

如果正则表达式中定义了组,就可以在Match对象上用group()方法提取出子串来。

注意到group(0)永远是原始字符串,group(1)、group(2)……表示第1、2、……个子串。

re.search()

search 函数和 match 函数是类似的,区别在于match方法是只在目标函数开头匹配一次;search函数是在整个目标函数上匹配一次,一次匹配成功后不再进行匹配。

同样search方法返回的也是一个match对象,用法和match方法返回的结果一样。

print(re.search('www', 'www.runoob.com').group())
print(re.search('com', 'www.runoob.com').group())

# www
# com

re.findall()

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。

注意 match 和 search 是匹配一次,findall 匹配所有。

函数语法:

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

参数:

string : 待匹配的字符串。
pos : 可选参数,指定字符串的起始位置,默认为 0。
endpos : 可选参数,指定字符串的结束位置,默认为字符串的长度。

# 查找字符串中的所有数字
print(re.findall('[0-9]', 'asodi92kjsdc980'))

# ['9', '2', '9', '8', '0']

re.split()

split 方法按照能够匹配的子串将字符串分割后返回列表.

函数语法:

re.split(pattern, string[, maxsplit=0, flags=0])

参数:

参数 描述
pattern 匹配的正则表达式
string 要匹配的字符串。
maxsplit 分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

s = '9-2*5/3+7/3*99/4*2998+10*568/14'
print(re.split(r"[\*\-\/\+]", s))

# ['9', '2', '5', '3', '7', '3', '99', '4', '2998', '10', '568', '14']

re.sub()

Python 的 re 模块提供了re.sub用于替换字符串中的匹配项。

函数语法:

re.sub(pattern, repl, string, count=0, flags=0)

参数:

pattern : 正则中的模式字符串。

repl : 替换的字符串,也可为一个函数。

string : 要被查找替换的原始字符串。

count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。

phone = "2004-959-559 # 这是一个国外电话号码"

# 删除字符串中的 Python注释
num = re.sub(r'#.*$', "", phone)
print("电话号码是: ", num)


# 删除非数字(-)的字符串
num = re.sub(r'\D', "", phone)
print("电话号码是: ", num)

'''
电话号码是:  2004-959-559 
电话号码是:  2004959559
'''

review:

'* ' 对它前面的正则式匹配0到任意次重复, 尽量多的匹配字符串。

'$' 匹配字符串尾或者换行符的前一个字符

re.compile()

compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。

函数语法:

re.compile(pattern[, flags])

参数:

pattern : 一个字符串形式的正则表达式

flags : 可选,表示匹配模式,比如忽略大小写,多行模式等

pattern = re.compile(r'[0-9]+')   # 用于匹配至少一个数字
print(pattern.match('one1twe2'))  # 查找头部,没有匹配

# None
m = re.compile(r'\d+')
print(m.match('one1twe2', 3, 7))  # 从1位置开始匹配,正好匹配

# <re.Match object; span=(3, 4), match='1'>

关于re.complie()方法中嵌套的括号,参考链接:

https://blog.csdn.net/qq_41424519/article/details/88527541

posted @ 2020-01-16 16:25  彩虹然  阅读(992)  评论(0编辑  收藏  举报