正则表达式
搭配[[Python]]
参考[[中谷教育-Python视频教程-26-正则表达式-初识]]
参考正则表达式教程
工具正则测试网站
参考Python正则表达式,这一篇就够了! learning
参考[[字符编码]]
Python正则表达式,这一篇就够了!
re模块简介
re模块主要定义了9个常量、12个函数、1个异常。
re模块常量
常量 | 语法 | 作用 |
---|---|---|
IGNORECASE | re.IGNORECASE 或简写为 re.I | 进行忽略大小写匹配。 |
ASCII | re.ASCII 或简写为 re.A | 顾名思义,ASCII表示ASCII码的意思,让 \w, \W, \b, \B, \d, \D, \s 和 \S 只匹配ASCII,而不是Unicode。 |
DOTALL | re.DOTALL 或简写为 re.S | DOT表示. ,ALL表示所有,连起来就是. 匹配所有,包括换行符\n 。默认模式下. 是不能匹配行符\n 的。 |
MULTILINE | re.MULTILINE 或简写为 re.M | 多行模式,当某字符串中有换行符\n ,默认模式下是不支持换行符特性的,比如:行开头 和 行结尾,而多行模式下是支持匹配行开头的。 |
VERBOSE | re.VERBOSE 或简写为 re.X | re.VERBOSE 或简写为 re.X |
LOCALE | re.LOCALE 或简写为 re.L | 由当前语言区域决定 \w , \W , \b , \B 和大小写敏感匹配,这个标记只能对byte样式有效。这个标记官方已经不推荐使用,因为语言区域机制很不可靠,它一次只能处理一个 "习惯”,而且只对8位字节有效。 |
UNICODE | re.UNICODE 或简写为 re.U | 与 ASCII 模式类似,匹配unicode编码支持的字符,但是 Python 3 默认字符串已经是Unicode,所以有点冗余。 |
DEBUG | re.DEBUG | 显示编译时的debug信息。 |
TEMPLATE | re.TEMPLATE 或简写为 re.T | 猪哥也没搞懂TEMPLATE的具体用处,源码注释中写着:disable backtracking(禁用回溯),有了解的同学可以留言告知! |
常量总结
- 9个常量中,前5个(IGNORECASE、ASCII、DOTALL、MULTILINE、VERBOSE)有用处,两个(LOCALE、UNICODE)官方不建议使用、两个(TEMPLATE、DEBUG)试验性功能,不能依赖。
- 常量在re常用函数中都可以使用,查看源码可得知。
- 常量可叠加使用,因为常量值都是2的幂次方值,所以是可以叠加使用的,叠加时请使用
|
符号,请勿使用+
符号!
re模块函数
re模块有12个函数,猪哥将以功能分类来讲解;这样更具有比较性,同时也方便记忆。
查找一个匹配项
查找并返回一个匹配项的函数有3个:search、match、fullmatch,他们的区别分别是:
- search: 查找任意位置的匹配项
- match: 必须从字符串开头匹配
- fullmatch: 整个字符串与正则完全匹配
案例1
import re
text = 'a猪哥大帅b,猪哥大帅b'
pattern = r'猪哥大帅b'
print('search:',re.search(pattern,text).group())
print('search:',re.search(pattern,text))
print('match:',re.match(pattern,text))
print('fullmatch',re.fullmatch(pattern,text))
输出
search: 猪哥大帅b
search: <re.Match object; span=(1, 6), match='猪哥大帅b'>
match: None
fullmatch None
案例2
text = '猪哥大帅b,猪哥大帅b'
pattern = r'猪哥大帅b'
print('search:',re.search(pattern,text).group())
print('search:',re.search(pattern,text))
print('match:',re.match(pattern,text).group())
print('match:',re.match(pattern,text))
print('fullmatch',re.fullmatch(pattern,text))
输出:
search: 猪哥大帅b
search: <re.Match object; span=(0, 5), match='猪哥大帅b'>
match: 猪哥大帅b
match: <re.Match object; span=(0, 5), match='猪哥大帅b'> fullmatch None
案例3
text = '猪哥大帅b'
pattern = r'猪哥大帅b'
print('search:',re.search(pattern,text).group())
print('search:',re.search(pattern,text))
print('match:',re.match(pattern,text).group())
print('match:',re.match(pattern,text))
print('fullmatch',re.fullmatch(pattern,text).group())
print('fullmatch',re.fullmatch(pattern,text))
输出:
search: 猪哥大帅b
search: <re.Match object; span=(0, 5), match='猪哥大帅b'>
match: 猪哥大帅b
match: <re.Match object; span=(0, 5), match='猪哥大帅b'>
fullmatch 猪哥大帅b
fullmatch <re.Match object; span=(0, 5), match='猪哥大帅b'>
查找多个匹配项
查找多项函数主要有:findall函数 与 finditer函数:
- findall: 从字符串任意位置查找,返回一个列表
- finditer:从字符串任意位置查找,返回一个迭代器
两个方法基本类似,只不过一个是返回列表,一个是返回迭代器。我们知道列表是一次性生成在内存中,而迭代器是需要使用时一点一点生成出来的,内存使用更优。
案例4
text = 'a猪哥大帅b,猪哥大帅b'
pattern = r'猪哥大帅b'
print('findall:',re.findall(pattern,text))
print('finditer:',list(re.finditer(pattern,text)))
输出:
findall: ['猪哥大帅b', '猪哥大帅b']
finditer: [<re.Match object; span=(1, 6), match='猪哥大帅b'>, <re.Match object; span=(7, 12), match='猪哥大帅b'>]
分割
re.split(pattern, string, maxsplit=0, flags=0) 函数:用 pattern 分开 string , maxsplit表示最多进行分割次数, flags表示模式,就是上面我们讲解的常量!
案例5
import re
text = 'a猪哥大帅b,b猪哥大帅b,c猪哥大帅b'
pattern = r','
print('split:',re.split(pattern,text,maxsplit=999,flags=re.IGNORECASE))
输出:
split: ['a猪哥大帅b', 'b猪哥大帅b', 'c猪哥大帅b']
注意:str
模块也有一个 split函数 ,那这两个函数该怎么选呢?
str.split函数功能简单,不支持正则分割,而re.split支持正则。
1000次循环以内str.split
函数更快,而循环次数1000次以上后re.split
函数明显更快,而且次数越多差距越大!
所以结论是:在 不需要正则支持 且 数据量和数次不多 的情况下使用str.split
函数更合适,反之则使用re.split
函数。
替換
替换主要有sub函数 与 subn函数,他们功能类似!
先来看看sub函数的用法:
re.sub(pattern, repl, string, count=0, flags=0) 函数参数讲解:repl替换掉string中被pattern匹配的字符, count表示最大替换次数,flags表示正则表达式的常量。
值得注意的是:sub函数中的入参:repl替换内容既可以是字符串,也可以是一个函数哦! 如果repl为函数时,只能有一个入参:Match匹配对象。
案例6
import re
text = '1猪哥大帅b,1猪哥大帅b,3猪哥大帅b'
pattern = r','
rep1 = '、'
print('sub-rep1为字符串:',re.sub(pattern,rep1,text,count=2,flags=re.IGNORECASE))
输出:
ub-rep1为字符串: 1猪哥大帅b、1猪哥大帅b、3猪哥大帅b
案例7
text = '1猪哥大帅b,2猪哥大帅b。3猪哥大帅b'
pattern = r',|。'
rep1 = lambda matchobj: ' ' if matchobj.group(0) != ',' else '、'
print('sub-rep1为函数:',re.sub(pattern,rep1,text,count=2,flags=re.IGNORECASE))
输出:
sub-rep1为函数: 1猪哥大帅b、2猪哥大帅b 3猪哥大帅b
定义
定义:正则表达式(regexp或者re)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过re模块实现。
概括
-
正则表达式模式被编译成一系列的字节码,然后由C编写的匹配引擎执行。
-
正则表达式语言相对小型和受限(功能有限)
- 并非所有字符串处理都可以用正则表达式完成。
-
字符匹配
- 普通字符
- 大部分字母和字符一般都会和自身匹配
- 如正则表达式test会和字符串"test"完全匹配
- 元字符
. ^ $ * + ? {} [] \ | ()
- 普通字符
-
[]
- 常用来制定一个字符集:
[abc]
;[a-z]
- 元字符在字符集中不起作用:
[akm$]
- 补集匹配不在区间范围内的字符:
[^5]
- 常用来制定一个字符集:
-
^
- 匹配行首。除非设置MULTILINE标志,它只是匹配字符串的开始。在MULTILINE模式里,它可以直接匹配字符串中的每个换行。
-
$
- 匹配行尾,行尾被定义为要么是字符串尾,要么是一个换行字符后面的任何位置。
在python中使用正则表达式
需要导入re模块import re
定义正则表达式就是在定义一个字符串。
在python中使用[]
>>> import re
>>> s = r'abc'
>>> re.findall(s,"aaaaaaaaaaaaaaaaaaaaaaaaabcdef")
['abc']
>>> re.findall(s,"aaaaaaaabcdfaaaaaaaaaaaaaaaaabcdef")
['abc', 'abc']
>>> st = "top tip tqp twp tep"
>>> res = r"top"
>>> re.findall(res,st)
['top']
>>>
>>> res = r"tip"
>>> re.findall(res,st)
['tip']
>>>
>>> res = r"t[io]p"
>>> re.findall(res,st)
['top', 'tip']
>>>
>>> res = r"t[^io]p"
>>> re.findall(res,st)
['tqp', 'twp', 'tep']