python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python正则表达式模块

Python中的re正则表达式模块

作者:springsnow

这篇文章介绍了Python中的re正则表达式模块,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

一、re模块的基本使用

Python里数量词默认是贪婪的,总是尝试匹配尽可能多的字符。正则表达式是用来匹配处理字符串的。

假如你需要匹配文本中的字符\,Python里的使用原生字符串表示:r'\\'表示。同样,匹配一个数字的\\d可以写成r'\d'

1、python 中使用正则表达式需要引入re模块

import re  # 第一步,要引入re模块
a = re.findall("匹配规则", "这个字符串是否有匹配规则的字符")  # 第二步,调用模块函数
print(a)  # 以列表形式返回匹配到的字符串
# ['匹配规则']

2、常见元字符

二、re模块中常用功能函数

1、 正则表达式的两种书写方式

1、一种是直接在函数里书写规则,推荐使用

import re

a = re.findall("匹配规则", "这个字符串是否有匹配规则的字符")
print(a)  # ['匹配规则']

2、另一种是先将正则表达式的字符串形式编译为Pattern实例,然后使用Pattern实例处理文本并获得匹配结果(一个Match实例),最后使用Match实例获得信息,进行其他的操作。

re.compile(pattern[, flag])函数:用于将字符串形式的正则表达式编译为Pattern对象

这个方法是Pattern类的工厂方法。 第二个参数flag是匹配模式,取值可以使用按位或运算符'|'表示同时生效,比如re.I | re.M。

另外,你也可以直接在pattern字符串中指定模式,比如re.compile('pattern', re.I | re.M)与re.compile('(?im)pattern')是等价的。

import re

# 将正则表达式编译成Pattern对象
pattern = re.compile(r'hello')

# 使用Pattern匹配文本,获得匹配结果,无法匹配时将返回None
match = pattern.match('hello world!')

if match:
    # 使用Match获得分组信息
    print(match.group())  # hello

2、匹配模式

下表是所有的正则匹配模式:

1、 re.S:扩展

在Python的正则表达式中,有一个参数为re.S。它表示 “.” 的作用扩展到整个字符串,包括“\n”。看如下代码:

import re

a = '''asdfhellopass:
    worldaf
    '''
b = re.findall('hello(.*?)world', a)
c = re.findall('hello(.*?)world', a, re.S)
print('b is ', b)  # b is  []
print('c is ', c)  # c is  ['pass:\n    ']

正则表达式中,“.”的作用是匹配除“\n”以外的任何字符,也就是说,它是在一行中进行匹配。这里的“行”是以“\n”进行区分的。a字符串有每行的末尾有一个“\n”,不过它不可见。

如果不使用re.S参数,则只在每一行内进行匹配,如果一行没有,就换下一行重新开始,不会跨行。而使用re.S参数以后,正则表达式会将这个字符串作为一个整体,将“\n”当做一个普通的字符加入到这个字符串中,在整体中进行匹配。

2、 re.I:不区分大小写

import re

res = re.findall(r"A", "abc", re.I)
print(res)# ['a']

3、 分组函数

?P :(只对正则函数返回对象时有用)# ?P<>定义组里匹配内容的key(键),<>里面写key名称,值就是匹配到的内容

取出匹配对象三种方法:(只对正则函数返回对象的有用)

3、re.match(常用):从头匹配一个符合规则的字符串,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None

match(pattern, string, flags=0)

注意:match()函数 与 search()函数基本是一样的功能,不一样的就是match()匹配字符串开始位置的一个符合规则的字符串,search()是在字符串全局匹配第一个符合规则的字符串

import re

# 无分组
origin = "hello egon bcd egon lge egon acd 19"
r = re.match("h\w+", origin)  # match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None
print(r.group())  # 获取匹配到的所有结果,不管有没有分组将匹配到的全部拿出来
print(r.groups())  # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分的结果
print(r.groupdict())  # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分定义了key的组结果
# hello
# ()
# {}

# 有分组
# 为何要有分组?提取匹配成功的指定内容(先匹配成功全部正则,再匹配成功的局部内容提取出来)
r = re.match("h(\w+)", origin)  # match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None
print(r.group())  # 获取匹配到的所有结果,不管有没有分组将匹配到的全部拿出来
print(r.groups())  # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分的结果
print(r.groupdict())  # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分定义了key的组结果
# hello
# ('ello',)
# {}

# 有两个分组定义了key
# 为何要有分组?提取匹配成功的指定内容(先匹配成功全部正则,再匹配成功的局部内容提取出来)
# ?P<>定义组里匹配内容的key(键),<>里面写key名称,值就是匹配到的内容
r = re.match("(?Ph)(?P\w+)", origin)
print(r.group())  # 获取匹配到的所有结果,不管有没有分组将匹配到的全部拿出来
print(r.groups())  # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分的结果
print(r.groupdict())  # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分定义了key的组结果
# hello
# ('h', 'ello')
# {'n1': 'h', 'n2': 'ello'}

4、 re.search(pattern, string[, flags]):浏览整个字符串去匹配第一个符合规则的字符串,未匹配成功返回None

search(pattern, string, flags=0)

注意:match()函数 与 search()函数基本是一样的功能,不一样的就是match()匹配字符串开始位置的一个符合规则的字符串,search()是在字符串全局匹配第一个符合规则的字符串

import re

# 无分组
origin = "hello alex bcd alex lge alex acd 19"
# search浏览全部字符串,匹配第一符合规则的字符串,浏览整个字符串去匹配第一个,未匹配成功返回None
r = re.search("a\w+", origin)
print(r.group() )  # 获取匹配到的所有结果,不管有没有分组将匹配到的全部拿出来
print(r.groups() )  # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分的结果
print(r.groupdict() )  # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分定义了key的组结果
# alex
# ()
# {}

# 有分组
# 为何要有分组?提取匹配成功的指定内容(先匹配成功全部正则,再匹配成功的局部内容提取出来)
r = re.search("a(\w+).*(\d)", origin)
print(r.group())  # 获取匹配到的所有结果,不管有没有分组将匹配到的全部拿出来
print(r.groups())  # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分的结果
print(r.groupdict())  # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分定义了key的组结果
# alex bcd alex lge alex acd 19
# ('lex', '9')
# {}

# 有两个分组定义了key
# 为何要有分组?提取匹配成功的指定内容(先匹配成功全部正则,再匹配成功的局部内容提取出来)
# ?P<>定义组里匹配内容的key(键),<>里面写key名称,值就是匹配到的内容
r = re.search("a(?P\w+).*(?P\d)", origin)
print(r.group())  # 获取匹配到的所有结果,不管有没有分组将匹配到的全部拿出来
print(r.groups())  # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分的结果
print(r.groupdict())  # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分定义了key的组结果
# alex bcd alex lge alex acd 19
# ('lex', '9')
# {'n1': 'lex', 'n2': '9'}

5、 re.findall()(常用):浏览全部字符串,匹配所有合规则的字符串,匹配到的字符串放到一个列表中,未匹配成功返回空列表

findall(pattern, string, flags=0)

注意:一旦匹配成,再次匹配,是从前一次匹配成功的,后面一位开始的,也可以理解为匹配成功的字符串,不在参与下次匹配。

1、无分组:匹配所有合规则的字符串,匹配到的字符串放到一个列表中

import re
# 无分组
r = re.findall("\d+\w\d+", "a2b3c4d5")  # 浏览全部字符串,匹配所有合规则的字符串,匹配到的字符串放到一个列表中
print(r)  # 注意:匹配成功的字符串,不在参与下次匹配,所以3c4也符合规则但是没匹配到
# ['2b3', '4d5']

注意:如果没写匹配规则,也就是空规则,返回的是一个比原始字符串多一位的,空字符串列表

import re
# 无分组
r = re.findall("", "a2b3c4d5")  # 浏览全部字符串,匹配所有合规则的字符串,匹配到的字符串放到一个列表中
print(r)  # 注意:如果没写匹配规则,也就是空规则,返回的是一个比原始字符串多一位的,空字符串列表
# ['', '', '', '', '', '', '', '', '']

2、有分组:只将匹配到的字符串里组的部分放到列表里返回,相当于groups()方法

import re
origin = "hello alex bcd alex lge alex acd 19"
r = re.findall("a(\w+)", origin)  # 有分组:只将匹配到的字符串里,组的部分放到列表里返回
print(r)
# ['lex', 'lex', 'lex', 'cd']

注意:如果规则里只有一个组,而组后面是就表示组里的内容可以是0个或者多个,这样组里就有了两个意思,一个意思是匹配组里的内容,二个意思是匹配组里0内容(即是空白),所以尽量避免使用,否则会有可能匹配出空字符串

import re
origin = "hello alex bcd alex lge alex acd 19"
r = re.findall("(a)*", origin)
print(r)
# ['', '', '', '', '', '', 'a', '', '', '', '', '', '', '', '', 'a', '', '', '', '', '', '', '', '', 'a', '', '', '', '', 'a', '', '', '', '', '', '']

3、多个分组:只将匹配到的字符串里组的部分放到一个元组中,最后将所有元组放到一个列表里返回。

相当于在group()结果里再将组的部分,分别拿出来放入一个元组,最后将所有元组放入一个列表返回

import re
origin = "hello alex bcd alex lge alex acd 19"
# 多个分组:只将匹配到的字符串里,组的部分放到一个元组中,最后将所有元组放到一个列表里返回
r = re.findall("(a)(\w+)", origin)
print(r)
# [('a', 'lex'), ('a', 'lex'), ('a', 'lex'), ('a', 'cd')]

4、分组中有分组:只将匹配到的字符串里组的部分放到一个元组中,先将包含有组的组,看作一个整体也就是一个组,把这个整体组放入一个元组里,然后在把组里的组放入一个元组,最后将所有组放入一个列表返回

import re
origin = "hello alex bcd alex lge alex acd 19"
# 分组中有分组:只将匹配到的字符串里,组的部分放到一个元组中,先将包含有组的组,看作一个整体也就是一个组,把这个整体组放入一个元组里,然后在把组里的组放入一个元组,最后将所有组放入一个列表返回
r = re.findall("(a)(\w+(e))", origin)
print(r)
# [('a', 'le', 'e'), ('a', 'le', 'e'), ('a', 'le', 'e')]

5、?:在有分组的情况下findall()函数,不只拿分组里的字符串,拿所有匹配到的字符串。

注意?:只用于不是返回正则对象的函数如findall()

import re
origin = "hello alex bcd alex lge alex acd 19"
# ?:在有分组的情况下,不只拿分组里的字符串,拿所有匹配到的字符串,注意?:只用于不是返回正则对象的函数如findall()
b = re.findall("a(?:\w+)", origin)
print(b)
# ['alex', 'alex', 'alex', 'acd']

6、re.split():根据正则匹配分割字符串,返回分割后的一个列表

split(pattern, string, maxsplit=0, flags=0)

按照一个字符将全部字符串进行分割

import re
origin = "hello alex bcd alex lge alex acd 19"
r = re.split("a", origin)  # 根据正则匹配分割字符串
print(r)
# ['hello ', 'lex bcd ', 'lex lge ', 'lex ', 'cd 19']

将匹配到的字符串作为分割标准进行分割

import re
origin = "hello alex bcd alex lge alex 2acd 19"
r = re.split("a\w+", origin)  # 根据正则匹配分割字符串
print(r)
# ['hello ', ' bcd ', ' lge ', ' 2', ' 19']

7、 re.sub():替换匹配成功的指定位置字符串

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

import re
origin = "hello alex bcd alex lge alex acd 19"
r = re.sub("a", "替换", origin)  # 替换匹配成功的指定位置字符串
print(r)
# hello 替换lex bcd 替换lex lge 替换lex 替换cd 19

l = ['1 2 ', '2   3', '  3 4']
print(eval(re.sub(r'\s*', '', str(l))))
# ['12', '23', '34']

8、 re.subn():替换匹配成功的指定位置字符串,并且返回替换次数,可以用两个变量分别接受

subn(pattern, repl, string, count=0, flags=0)

import re

origin = "hello alex bcd alex lge alex acd 19"
a, b = re.subn("a", "替换", origin)  # 替换匹配成功的指定位置字符串,并且返回替换次数,可以用两个变量分别接受
print(a)  # hello 替换lex bcd 替换lex lge 替换lex 替换cd 19
print(b)  # 4

到此这篇关于Python正则表达式模块的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文