Python常用模块6-Python的re模块简介

一.re模块简介

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

模式和被搜索的字符串既可以是 Unicode 字符串 (str) ,也可以是8位字节串 (bytes)。 但是,Unicode 字符串与8位字节串不能混用:也就是说,你不能用一个字节串模式去匹配 Unicode 字符串,反之亦然;类似地,当进行替换操作时,替换字符串的类型也必须与所用的模式和搜索字符串的类型一致。

正则表达式使用反斜杠(’’)来表示特殊形式,或者把特殊字符转义成普通字符。 而反斜杠在普通的 Python 字符串里也有相同的作用,所以就产生了冲突。比如说,要匹配一个字面上的反斜杠,正则表达式模式不得不写成 ‘\\’,因为正则表达式里匹配一个反斜杠必须是 \ ,而每个反斜杠在普通的 Python 字符串里都要写成 \ 。

解决办法是对于正则表达式样式使用 Python 的原始字符串表示法;在带有 ‘r’ 前缀的字符串字面值中,反斜杠不必做任何特殊处理。 因此 r"\n" 表示包含 ‘’ 和 ‘n’ 两个字符的字符串,而 “\n” 则表示只包含一个换行符的字符串。 样式在 Python 代码中通常都会使用这种原始字符串表示法来表示。

绝大部分正则表达式操作都提供为模块函数和方法,在 编译正则表达式. 这些函数是一个捷径,不需要先编译一个正则对象,但是损失了一些优化参数。

第三方模块 regex , 提供了与标准库 re 模块兼容的API接口, 同时还提供了额外的功能和更全面的Unicode支持。

1.1 匹配符

python的匹配符比较多,下面罗列一些常用的。

常用配符概述
.(点) 在默认模式,匹配除了换行的任意字符。如果指定了标签 DOTALL ,它将匹配包括换行符的任意字符。
^(插入符号) 匹配字符串的开头, 并且在 MULTILINE 模式也匹配换行后的首个符号
$匹配字符串尾或者在字符串尾的换行符的前一个字符,在 MULTILINE 模式下也会匹配换行符之前的文本。
*对它前面的正则式匹配0到任意次重复, 尽量多的匹配字符串。 ab* 会匹配 ‘a’,‘ab’,或者 ‘a’ 后面跟随任意个 ‘b’。
+对它前面的正则式匹配1到任意次重复。 ab+ 会匹配 ‘a’ 后面跟随1个以上到任意个 ‘b’,它不会匹配 ‘a’。
?对它前面的正则式匹配0到1次重复。 ab? 会匹配 ‘a’ 或者 ‘ab’。
\转义特殊字符(允许你匹配 ‘*’, ‘?’, 或者此类其他),或者表示一个特殊序列;特殊序列之后进行讨论。
|A|B, 匹配A或者B,A成功了,就不会匹配B
[]用于表示一个字符集合,比如 [amk] 匹配 ‘a’, ‘m’, 或者 ‘k’

1.1.1 字符集合

字符匹配的字符
\number匹配数字代表的组合。
\A只匹配字符串开始
\b匹配空字符串,但只在单词开始或结尾的位置。
\B匹配空字符串,但 不 能在词的开头或者结尾
\d匹配任何十进制数,就是 [0-9]
\D匹配非[0-9]的数字,与\d 相反
\s匹配ASCII中的空白字符,就是 [ \t\n\r\f\v] 。
\S匹配任何不是空白字符的字符,与\s相反
\w匹配ASCII字符中的数字和字母和下划线,就是 [a-zA-Z0-9_] 。
\W匹配任何不是单词字符的字符,与\w相反
\Z只匹配字符串尾。

1.1.2 重复次数

贪婪模式会获取尽可能多的字符,而非贪婪模式会获取尽可能少的字符。

贪婪非贪婪描述
**?零次或多次
???零次或一次
++?一次或多次
{m}{m}?正好m次,贪婪与非贪婪一样的,比如, a{6} 将匹配6个 ‘a’
{m,}{m,}?至少m次, 比如 a{4,}b 将匹配 ‘aaaab’ 或者1000个 ‘a’ 尾随一个 ‘b’,但不能匹配 ‘aaab’
{m, n}{m, n}?最少m最多n次,比如,对于 ‘aaaaaa’, a{3,5} 匹配 5个 ‘a’ ,而 a{3,5}? 只匹配3个 ‘a’

1.1.3 组合匹配符

组合匹配是多个匹配规则配合起来。
例如,我要匹配身份证号码

^[1-9]\d{13,16}[0-9x]$

上面这个代码有3个部分

  1. 1 开头是1-9的一个数字
  2. \d{13,16} 中间是最少13个数字,最多16个数字
  3. [0-9xX]$ 结尾是0-9、x或者X中的一个
组合匹配符概述
(…)(组合),匹配括号内的任意正则表达式,并标识出组合的开始和结尾。匹配完成后,组合的内容可以被获取,并可以在之后用 \number 转义序列进行再次匹配,之后进行详细说明。要匹配字符 ‘(’ 或者 ‘)’, 用 ( 或 ), 或者把它们包含在字符集合里: [(], [)].
(?…)这是个扩展标记法 (一个 ‘?’ 跟随 ‘(’ 并无含义)。 ‘?’ 后面的第一个字符决定了这个构建采用什么样的语法。
(?aiLmsux)( ‘a’, ‘i’, ‘L’, ‘m’, ‘s’, ‘u’, ‘x’ 中的一个或多个) 这个组合匹配一个空字符串;这
(?:…)正则括号的非捕获版本。 匹配在括号内的任何正则表达式,但该分组所匹配的子字符串 不能 在执行匹配后被获取或是之后在模式中被引用。
(?#…)注释;里面的内容会被忽略。
(?=…)匹配 … 的内容,但是并不消费样式的内容。这个叫做 lookahead assertion。比如, Isaac (?=Asimov) 匹配 'Isaac ’ 只有在后面是 ‘Asimov’ 的时候。
(?!…)匹配 … 不符合的情况。这个叫 negative lookahead assertion (前视取反)。比如说, Isaac (?!Asimov) 只有后面 不 是 ‘Asimov’ 的时候才匹配 'Isaac ’ 。
(?<=…)匹配字符串的当前位置,它的前面匹配 … 的内容到当前位置
(?<!…)匹配当前位置之前不是 … 的样式。
(?(id/name)yes-pattern|no-pattern)如果给定的 id 或 name 存在,将会尝试匹配 yes-pattern ,否则就尝试匹配 no-pattern,no-pattern 可选,也可以被忽略。

二.模块内容

模块定义了几个函数,常量,和一个例外。有些函数是编译后的正则表达式方法的简化版本(少了一些特性)。绝大部分重要的应用,总是会先将正则表达式编译,之后在进行操作。

2.1 常用函数

函数概述
re.compile(pattern, flags=0)将一个正则表达式模式编译成一个正则表达式对象,可以使用它的match()、search()和其他方法进行匹配,如果需要多次使用这个正则表达式的话,使用 re.compile() 和保存这个正则对象以便复用,可以让程序更加高效。
re.I/re.IGNORECASE进行忽略大小写匹配;表达式如 [A-Z] 也会匹配小写字符。Unicode匹配(比如 Ü 匹配 ü)同样有用,除非设置了 re.ASCII 标记来禁用非ASCII匹配。当前语言区域不会改变这个标记,除非设置了 re.LOCALE 标记。这个相当于内联标记
re.L/re.LOCALE由当前语言区域决定 \w, \W, \b, \B 和大小写敏感匹配。这个标记只能对byte样式有效。这个标记不推荐使用,因为语言区域机制很不可靠,它一次只能处理一个 “习惯”,而且只对8位字节有效。
re.M/re.MULTILINE设置以后,样式字符 ‘^’ 匹配字符串的开始,和每一行的开始(换行符后面紧跟的符号);样式字符 ‘ ′ 匹 配 字 符 串 尾 , 和 每 一 行 的 结 尾 ( 换 行 符 前 面 那 个 符 号 ) 。 默 认 情 况 下 , ’ ’ 匹 配 字 符 串 头 , ′ ' 匹配字符串尾,和每一行的结尾(换行符前面那个符号)。默认情况下,’^’ 匹配字符串头,' ’ 匹配字符串尾。对应内联标记 (?m) 。
re.S/re.DOTALL让 ‘.’ 特殊字符匹配任何字符,包括换行符;如果没有这个标记,’.’ 就匹配 除了 换行符的其他任意字符。
re.X/re.VERBOSE这个标记允许你编写更具可读性更友好的正则表达式。通过分段和添加注释。空白符号会被忽略,除非在一个字符集合当中或者由反斜杠转义,或者在 *?, (?: or (?P<…> 分组之内。当一个行内有 # 不在字符集和转义序列,那么它之后的所有字符都是注释。
re.search(pattern, string, flags=0)扫描整个 字符串 找到匹配样式的第一个位置,并返回一个相应的 匹配对象。如果没有匹配,就返回一个 None ; 注意这和找到一个零长度匹配是不同的。
re.match(pattern, string, flags=0)如果 string 开始的0或者多个字符匹配到了正则表达式样式,就返回一个相应的 匹配对象 。 如果没有匹配,就返回 None ;注意它跟零长度匹配是不同的。
注意即便是 MULTILINE 多行模式, re.match() 也只匹配字符串的开始位置,而不匹配每行开始。
如果你想定位 string 的任何位置,使用 search() 来替代(也可参考 search() vs. match() )
re.fullmatch(pattern, string, flags=0)如果整个 string 匹配到正则表达式样式,就返回一个相应的 匹配对象 。 否则就返回一个 None ;注意这跟零长度匹配是不同的
re.split(pattern, string, maxsplit=0, flags=0)用 pattern 分开 string 。 如果在 pattern 中捕获到括号,那么所有的组里的文字也会包含在列表里。如果 maxsplit 非零, 最多进行 maxsplit 次分隔, 剩下的字符全部返回到列表的最后一个元素
re.findall(pattern, string, flags=0)对 string 返回一个不重复的 pattern 的匹配列表, string 从左到右进行扫描,匹配按找到的顺序返回。如果样式里存在一到多个组,就返回一个组合列表;就是一个元组的列表(如果样式里有超过一个组合的话)。空匹配也会包含在结果里。
re.escape(pattern)转义除ASCII字母、数字和’_'之外的模式中的所有字符。如果您想要匹配任意可能包含正则表达式元字符的字面值字符串,这是非常有用的
re.purge()清除正则表达式缓存。

2.2 异常

exception re.error(msg, pattern=None, pos=None)
raise 一个例外。当传递到函数的字符串不是一个有效正则表达式的时候(比如,包含一个不匹配的括号)或者其他错误在编译时或匹配时产生。如果字符串不包含样式匹配,是不会被视为错误的。

属性
msg未格式化的错误消息。
pattern正则表达式样式
pos编译失败的 pattern 的位置索引(可以是 None )。
lineno对应 pos (可以是 None) 的行号。
colno对应 pos (可以是 None) 的列号。

2.3 匹配对象

re.search、re.match、re.fullmatch、re.finditer 都支持匹配对象

匹配对象支持以下方法和属性

属性描述
match.expand(template)返回通过在模板字符串模板上执行反斜杠替换获得的字符串,就像sub()方法那样。转义(例如\n)被转换为适当的字符,数字反向引用(\1,\2)和命名反向引用(\g<1>, \g)被相应组的内容替换。
match.group([group1, …])返回一个或者多个匹配的子组。如果只有一个参数,结果就是一个字符串,如果有多个参数,结果就是一个元组(每个参数对应一个项),如果没有参数,组1默认到0(整个匹配都被返回)。
match.getitem(g)这个等价于 m.group(g)。这允许更方便的引用一个匹配
match.groups(default=None)返回一个元组,包含所有匹配的子组,在样式中出现的从1到任意多的组合。 default 参数用于不参与匹配的情况,默认为 None。
match.groupdict(default=None)返回一个字典,包含了所有的 命名 子组。key就是组名。 default 参数用于不参与匹配的组合;默认为 None
match.start([group])返回 group 匹配到的字串的开始标号
match.end([group])返回 group 匹配到的字串的结束标号
match.span([group])对于一个匹配 m , 返回一个二元组 (m.start(group), m.end(group))
match.pospos的值,传递给regex对象的search()或match()方法。这是RE引擎不能超越的字符串索引。
match.endposendpos的值,传递给regex对象的search()或match()方法。这是RE引擎不能超越的字符串索引。
match.lastindex捕获组的最后一个匹配的整数索引值,或者 None 如果没有匹配产生的话。
match.lastgroup最后一个匹配的命名组名字,或者 None 如果没有产生匹配的话。
match.rematch()或search()方法产生这个匹配实例的正则表达式对象
match.string传递给match()或search()的字符串

三.正则案例

3.1 re.search

语法:

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

函数参数说明:

参数描述
pattern匹配的正则表达式
string要匹配的字符串
flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等
re.I (ignore case), re.M (multi-line), re.S (dot matches all), and re.X (verbose)

扫描整个 字符串 找到匹配样式的第一个位置,并返回一个相应的 匹配对象。如果没有匹配,就返回一个 None ; 注意这和找到一个零长度匹配是不同的。

代码:

import re


# 匹配是否存在
content1 = "I love python,I'm studying python!"
result1 = re.search('python', content1)

# 如果匹配成功输出结果,否则输出"匹配失败"
if result1:
    print(result1.group())
else:
    print("匹配失败")


content2 = "I love python,I'm studying python!"
result2 = re.search('test', content2)

# 如果匹配成功输出结果,否则输出"匹配失败"
if result2:
    print(result2.group())
else:
    print("匹配失败")

print("\n")
# 匹配数字
content = 'Hello 123456789 Word_This is just a test 666 Test'
result = re.search('(\d+).*?(\d+).*', content)

print(result)
print(result.group())  # print(result.group(0)) 同样效果字符串
print(result.groups())
print(result.group(1))
print(result.group(2))

print(result.start())
print(result.end())
print(result.span())


print("\n")
# 匹配前3个单词
content = 'Hello 123456789 Word_This is just a test 666 Test'
result = re.search('([a-zA-Z]+).*?([a-zA-Z]+).*?([a-zA-Z]+)', content)

# 输出匹配的结果,是一串字符
print(result)
print(result.string)

# 输出group相关
print(result.group())  # print(result.group(0)) 同样效果字符串
print(result.groups())
print(result.group(1))
print(result.group(2))
print(result.group(3))

# 输出匹配的规则
print(result.re)

# 输出匹配开始和结尾 开始匹配的字符是 start+1
print(result.start())
print(result.end())
print(result.span())

# 输出字符的开始位置和结束位置
print(result.pos)
print(result.endpos)

# 输出组最后的标记
print(result.lastindex)
print(result.lastgroup)

测试记录:

E:\python\learn_python1\venv\Scripts\python.exe E:/python/learn_python1/re_test1.py
python
匹配失败


<_sre.SRE_Match object; span=(6, 49), match='123456789 Word_This is just a test 666 Test'>
123456789 Word_This is just a test 666 Test
('123456789', '666')
123456789
666
6
49
(6, 49)


<_sre.SRE_Match object; span=(0, 25), match='Hello 123456789 Word_This'>
Hello 123456789 Word_This is just a test 666 Test
Hello 123456789 Word_This
('Hello', 'Word', 'This')
Hello 123456789 Word_This
Hello
Word
This
re.compile('([a-zA-Z]+).*?([a-zA-Z]+).*?([a-zA-Z]+)')
0
25
(0, 25)
0
49
3
None

Process finished with exit code 0

3.2 re.match

语法:

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

函数参数说明:

参数描述
pattern匹配的正则表达式
string要匹配的字符串
flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等
re.I (ignore case), re.M (multi-line), re.S (dot matches all), and re.X (verbose)

如果 string 开始的0或者多个字符匹配到了正则表达式样式,就返回一个相应的 匹配对象 。 如果没有匹配,就返回 None ;注意它跟零长度匹配是不同的。
注意即便是 MULTILINE 多行模式, re.match() 也只匹配字符串的开始位置,而不匹配每行开始。
如果你想定位 string 的任何位置,使用 search() 来替代(也可参考 search() vs. match() )

匹配对象方法描述
group(num=0)匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
groups()返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。

Python 提供了两种不同的操作:基于 re.match() 检查字符串开头,或者 re.search() 检查字符串的任意位置(默认Perl中的行为)。


>>> re.match("c", "abcdef")    # No match
>>> re.search("c", "abcdef")   # Match
<_sre.SRE_Match object; span=(2, 3), match='c'>

-- 在 search() 中,可以用 '^' 作为开始来限制匹配到字符串的首位
>>> re.match("c", "abcdef")    # No match
>>> re.search("^c", "abcdef")  # No match
>>> re.search("^a", "abcdef")  # Match
<_sre.SRE_Match object; span=(0, 1), match='a'>

-- 注意 MULTILINE 多行模式中函数 match() 只匹配字符串的开始,但使用 search() 和以 '^' 开始的正则表达式会匹配每行的开始
>>> re.match('X', 'A\nB\nX', re.MULTILINE)  # No match
>>> re.search('^X', 'A\nB\nX', re.MULTILINE)  # Match
<_sre.SRE_Match object; span=(4, 5), match='X'>

3.3 re.fullmatch

语法:

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

函数参数说明:

参数描述
pattern匹配的正则表达式
string要匹配的字符串
flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等
re.I (ignore case), re.M (multi-line), re.S (dot matches all), and re.X (verbose)

如果整个 string 匹配到正则表达式样式,就返回一个相应的匹配对象 。 否则就返回一个 None ;注意这跟零长度匹配是不同的。

match从字符串开头开始匹配,匹配到目标的字符串即可成功返回(这个要跟search区分开,search不要求从头开始匹配);

fullmatch是完全匹配(从字符串开头到结尾)。

import re

qq = '1826755263'
re.match(r'[1-9]\d{4,11}', qq)

qq = '1826755263'
re.fullmatch(r'[1-9]\d{4,11}', qq)

# 用match实现fullmatch的功能
qq = '1826755263'
re.match(r'^[1-9]\d{4,11}$', qq)

3.4 re.split

语法:

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

函数参数说明:

参数描述
pattern匹配的正则表达式
string要匹配的字符串
maxsplit分隔次数,默认为0(即不限次数)
flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等
re.I (ignore case), re.M (multi-line), re.S (dot matches all), and re.X (verbose)

用 pattern 分开 string 。 如果在 pattern 中捕获到括号,那么所有的组里的文字也会包含在列表里。如果 maxsplit 非零, 最多进行 maxsplit 次分隔, 剩下的字符全部返回到列表的最后一个元素

>>> import re
>>> re.split(r'\W+','Words, words, words.')
['Words', 'words', 'words', '']
>>> re.split(r'(\W+)','Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
>>>
>>> re.split(r'\W+','Words, words, words.',1)
['Words', 'words, words.']
>>> re.split(r'\W+','Words, words, words.',2)
['Words', 'words', 'words.']
>>>
>>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)
['0', '3', '9']
>>>

3.5 re.findall

语法:

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

函数参数说明:

参数描述
pattern匹配的正则表达式
string要匹配的字符串
flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等
re.I (ignore case), re.M (multi-line), re.S (dot matches all), and re.X (verbose)

对 string 返回一个不重复的 pattern 的匹配列表, string 从左到右进行扫描,匹配按找到的顺序返回。如果样式里存在一到多个组,就返回一个组合列表;就是一个元组的列表(如果样式里有超过一个组合的话)。空匹配也会包含在结果里。

>>> import re
>>> text = "He was carefully disguised but captured quickly by police."
>>> re.findall(r"\w+ly", text)
['carefully', 'quickly']
>>>

参考:

1.https://docs.python.org/zh-cn/3.6/library/re.html
2.https://blog.csdn.net/u011649536/article/details/50587915


  1. 1-9 ↩︎

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值