简介
正则表达式本身是一种小型的、高度专业化的编程语言,它并不是Python的一部分。正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大。得益于这一点,在提供了正则表达式的语言里,正则表达式的语法都是一样的,区别只在于不同的编程语言实现支持的语法数量不同;但不用担心,不被支持的语法通常是不常用的部分。如果已经在其他语言里使用过正则表达式,只需要简单看一看就可以上手了。而在python中,通过内嵌集成re模块,程序员们可以直接调用来实现正则匹配。正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎执行。
元字符
字符 | 描述 |
---|---|
. | 匹配任意字符,除了' ' |
转义字符,使后一个字符改变原来的意思 如果字符串中有字符*需要匹配,可以使用*或者字符集[*] |
|
[] | 字符集。对应的位置可以是字符中任意字符。字符集可以逐个列出,也可以给出范围,例如:[abc]或者[a-c] 第一个字符如果是^表示取反,如[^abc]表示不是abc的 |
d | 数字: [0-9] |
D | 非数字: [^0-9] |
s | 空白字符: [<空格> fv] |
S | 非空白字符: [^s] |
w | 单词字符: [A-Z a-z 0-9] |
W | 非单词字符: [^w] |
* | 匹配前一个字符: 0~∞ |
+ | 匹配前一个字符: 1~∞ |
? | 匹配前一个字符0-1次 |
{m} | 匹配前一个字符m次 |
{m,n} | 匹配前一个字符m~n次 |
^ | 匹配字符串开头 在多行模式中,匹配每一行开头 |
$ | 匹配字符串结尾 在多行模式中,匹配每一行结尾 |
A | 仅匹配字符串开头 |
仅匹配字符串结尾 | |
匹配w和W之间 | |
B | [^] |
| | 代表匹配左右任何一个, 先匹配左边, 如果左边匹配不上再匹配右边, 如果左边匹配上了则不匹配右边 如果|没有在()里, 则它的范围是整个正则表达式 |
(....) | 被括起来的表达式将作为分组, 从表达式左边开始, 每遇到一个分组的左括号'(', 编号+1. 另外, 分组表达式作为一个整体, 可以后接数量词. 表达式中的|仅在该组中有效 |
(?P<name>...) | 分组,除了原有的编号外再指定一个额外的名字 |
<number> | 引用编号为<number>的分组匹配到的字符串 |
(?P=name) | 引用别名为<name>的分组匹配到的字符串 |
案例
import re
# 1. ^元字符: 字符串开始位置与匹配规则符合就匹配,否则不匹配
a = re.findall("^匹配规则", "匹配规则这个字符串是否匹配")
print(a) # ['匹配规则']
# 2. [^a-z]反取: ^元字符如果写到字符集里就是反取
a = re.findall("[^a-z]", "匹配s规则这s")
print(a) # ['匹', '配', '规', '则', '这']
# 3. $元字符: 字符串结束位置与匹配规则符合就匹配,否则不匹配
a = re.findall("匹配规则$", "这个字符串是否匹配规则")
print(a) # ['匹配规则']
# 4. *元字符: 匹配前一个字符0或多次
a = re.findall("匹配规则*", "这个字符串是否匹配规则则则则则")
print(a) # ['匹配规则则则则则']
# 5. +元字符: 匹配前一个字符1或多次
a = re.findall("匹配+", "匹配配配配配规则这个字符串是否匹配规则则则则则")
print(a) # ['匹配配配配配', '匹配']
# 6. ?元字符(防止贪婪匹配): 匹配一个字符0次或1次
a = re.findall("匹配规则?", "匹配规这个字符串是否匹配规则则则则则")
print(a) # ['匹配规', '匹配规则']
# 7. {}元字符(范围)
a = re.findall("匹配规则{3}", "匹配规这个字符串是否匹配规则则则则则")
print(a) # ['匹配规则则则']
# 8. []元字符(字符集)
a = re.findall("匹配[a,b,c]规则", "匹配a规则这个字符串是否匹配b规则则则则则")
print(a) # ['匹配a规则', '匹配b规则']
# 9. [^]: 非,反取,匹配出除[^]里面的字符
a = re.findall("[^a-z]", "匹配s规则这s个")
print(a) # ['匹', '配', '规', '则', '这', '个']
# 10. d: 匹配任何十进制数,它相当于类[0-9]
a = re.findall("d", "匹配规则这2个字符串3是否匹配规则5则则则7则")
print(a) # ['2', '3', '5', '7']
# 11. d+: 匹配一位或者多位数的数字时用
a = re.findall("d+", "匹配规则这2个字符串134444是否匹配规则5则则则7则")
print(a) # ['2', '134444', '5', '7']
# 12. D: 匹配任何非数字字符,它相当于类[^0-9]
a = re.findall("D", "这2个字符串3是")
print(a) # [ '这', '个', '字', '符', '串', '是']
# 13. s: 匹配任何空白字符,它相当于类[
fv]
a = re.findall("s", "匹配规则 这2个字符串3是否匹
配规则5则则则7则")
print(a) # [' ', ' ', ' ', '
']
# 14. S: 匹配任何非空白字符,它相当于类[^
fv]
a = re.findall("S", "匹配规则 这2个")
print(a) # ['匹', '配', '规', '则', '这', '2', '个']
# 15. w: 匹配包括下划线在内任何字母数字字符,它相当于类[a-zA-Z0-9_]
a = re.findall('w', "https://www.cnblogs.com/")
print(a) # ['h', 't', 't', 'p', 's', 'w', 'w', 'w', 'c', 'n', 'b', 'l', 'o', 'g', 's', 'c', 'o', 'm']
# 16. w: 匹配包括下划线在内任何字母数字字符,它相当于类[a-zA-Z0-9_]
a = re.findall('W', "https://www.cnblogs.com/")
print(a) # [':', '/', '/', '.', '.', '/']
# 17. ()元字符: 也就是分组匹配,()里面的为一个组也可以理解成一个整体
a = re.search("(a4)+", "a4a4a4a4a4dg4g654gb") # 匹配一个或多个a4
b = a.group()
print(b) # a4a4a4a4a4
a = re.search("a(d+)", "a466666664a4a4a4dg4g654gb")
b = a.group()
print(b) # a466666664
# 18. |元字符(或): 就是前后其中一个符合就匹配
a = re.findall(r"你|好", "a4a4a你4aabc4a4dgg好dg4g654g")
print(a) # ['你', '好']
常用函数
match
atch(pattern, string, flags=0)
在 string 起始位置开始匹配 pattern,flags 表示标志位
若匹配成功则返回 SRE_Match 对象,若匹配不成功则返回 None 对象
_sre.SRE_Match 对象常用的方法列举如下:
start([group])
:返回匹配开始的位置end([group])
:返回匹配结束的位置span([group])
:返回匹配的范围group(num=0)
:返回匹配的字符串,若对象中有子组,则加上 num 参数可获取相应子组
import re
result = re.match(r'abc(d+)', "abc123def456abc789")
type(result)
# <class '_sre.SRE_Match'>
result.start() # 查看匹配的起始位置
# 0
result.end() # 查看匹配的结束位置
# 6
result.span() # 查看匹配的范围
# (0, 6)
result.group() # 查看匹配的字符串
# 'abc123'
result.group(1) # 查看匹配的子组
# '123'
search
search(pattern, string, flags=0)
在 string 中搜索第一次出现的 pattern,flags 表示标志位
同样的,若匹配成功则返回 SRE_Match对象,若匹配不成功则返回 None对象
import re
result = re.search(r'abc(d+)', "abc123def456abc789")
type(result)
# <class '_sre.SRE_Match'>
result.span() # 查看匹配的范围
# (0, 6)
findall
findall(pattern, string, flags=0)
在 string 中搜索所有符合条件的 pattern,flags 表示标志位
一般情况下,该方法返回匹配内容的 列表,若匹配模式中含有子组,则返回对应的子组列表
import re
result = re.findall(r'abcd+', "abc123def456abc789") # 不含子组
type(result)
# <class 'list'>
for item in result:
print(item)
# abc123
# abc789
result = re.findall(r'abc(d+)', "abc123def456abc789") # 含有子组
type(result)
# <class 'list'>
for item in result:
print(item)
# 123
# 789
finditer
finditer(pattern, string, flags=0)
在 string 中搜索所有符合的 pattern,flags表示标志位
一般情况下,该方法返回匹配内容的 迭代器对象
import re
result = re.finditer(r'abc(d+)', "abc123def456abc789")
type(result)
# <class 'callable_iterator'>
for item in result:
print(item)
# <_sre.SRE_Match object; span=(0, 6), match='abc123'>
# <_sre.SRE_Match object; span=(12, 18), match='abc789'>
compile
compile(pattern, flags=0)
编译正则表达式模式为正则表达式对象
通常情况下,如果需要重复使用某个正则表达式,那么可以先将该正则表达式编译成模式对象,以下是参数说明:
- pattern :匹配模式,建议使用原始字符串表示
- flags :标志位,用于控制正则表达式的匹配方式,可选值如下,多个值之间用
|
分割:re.I
re.IGNORECASE
:不区分大小写re.L
re.LOCALE
:取决于当前语言环境re.S
re.DOTALL
:使.
匹配包括换行符在内的所有字符re.M
re.MULTILINE
:使^
匹配字符串的开头和每行的开头,使$
匹配字符串的结尾和每行的结尾re.U
re.Unicode
:根据Unicode字符集解析字符。这个标志影响w, W, , B
re.X
re.VERBOSE
:忽略规则表达式中的空白和注释,并允许使用 ’#’ 来引导一个注释。这样可以让你把规则写得更美观些。
该方法返回一个 SRE_Pattern对象,该对象常用的方法如下:
-
match(string[, pos[, endpos]])
用对象中的匹配模式匹配 string 的起始位置,该方法返回 SRE_Match 对象,用 pos 和 endpos 表示匹配的范围
-
search(string[, pos[, endpos]])
用对象中的匹配模式匹配 string,该方法返回 SRE_Match 对象,用 pos 和 endpos 表示匹配的范围
-
findall(string[, pos[, endpos]])
用对象中的匹配模式匹配 string,该方法返回列表,用 pos 和 endpos 表示匹配的范围
-
finditer(string[, pos[, endpos]])
用对象中的匹配模式匹配 string,该方法返回迭代器,用 pos 和 endpos 表示匹配的范围
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("aw+", origin) # 根据正则匹配分割字符串
print(r)
# ['hello ', ' bcd ', ' lge ', ' 2', ' 19']
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
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