Python_13_正则表达式_06_编译正则表达式

到此为止,所介绍的 Python 正则表达式内容足可以开发实际项目了。

但是为了提高效率, 还可以对 Python 正则表达式进行编译。

编译的正则表达式可以重复使用,这样能减少正则表达式的解析和验证,提高效率。

re 模块中的 compile() 函数可以编译正则表达式,compile() 函数语法如下:

re.compile(pattern[, flags=0])

其中:

  • 参数 pattern 是正则表达式
  • 参数 flags 是编译标志

compile() 函数返回一个编译的正则表达式对象 regex

13.6.1 已编译正则表达式对象

compile() 函数返回一个编译的正则表达式对象,该对象也提供了文本的匹配、查找和替换等操作的方法。

如下表所示是己编译正则表达式对象方法与 re 模块函数对照表:

常用函数已编译正则表达式对象方法Re模块函数
search()regex.search(string[, pos[,endpos]])re.search(pattern,string,flags = 0)
match()regex.match(string[, pos[,endpos]])re. match (pattern,string,flags = 0)
findall()regex.findall(string[, pos[,endpos]])re. findall (pattern,string,flags = 0)
finditer()regex.finditer(string[,pos[,endpos]])re. finditer(pattern,string,flags = 0)
sub()regex.sub(string[, pos[,endpos]])re.sub(pattern,repl,string,count,flags=0)
split()regex.split(string[, pos[,endpos]])re.split(pattern,string,maxsplit=0,flags=0)

正则表达式方法需要一个己编译的正则表达式对象才能调用,这些方法与 re 模块函数功能类似,这里不再一一赘述。

注意方法 search()match()findall()finditer() 中的参数 pos 为开始查找的索引,参数 endpos 为结束查找的索引。

示例代码如下:

import re

p = r"\w+@zhijieketang\.com"
regex = re.compile(p)
text = "Tony's email is tony_guan588@zhijieketang.com."

m = regex.search(text)
print(m)

m = regex.match(text)
print(m)

p = r"[Jj]ava"
regex = re.compile(p)
text = "I like Java and java."

match_list = regex.findall(text)
print(match_list)

match_iter = regex.finditer(text)
for m in match_iter:
    print(m.group())

p = r"\d+"

regex = re.compile(p)
text = "AB12CD34EF"

clist = regex.split(text)
print(clist)

repace_text = regex.sub(" ", text)
print(repace_text)

执行结果:

<re.Match object; span=(16, 45), match='tony_guan588@zhijieketang.com'>
None
['Java', 'java']
Java
java
['AB', 'CD', 'EF']
AB CD EF

上述代码都是编译正则表达式,然后通过己编译的正则表达式对象 regex 调用方法实现文本匹配、查找和替换等操作。这些方法与 re 模块函数类似。

13.6.2 编译标志

compile() 函数编译正则表达式对象时,还可以设置编译标志。
编译标志可以改变正则表达式引擎行为。

13.6.2.1 ASCII 和 Unicode

本节详细介绍几个常用的编译标志:
1:ASCII 和 Unicode
预定义字符 \w\W,其中 \w 匹配单词字符,在 Python 2 中是 ASCII 编码,在 Python3 中则是 Unicode 编码,所以包含任何语言的单词字符。

可以通过编译标志 re.ASCII(或 re.A)设置采用 ASCII 编码,通过编译标志 re.UNICODE(或 re.U)设置采用 Unicode 编码。

示例代码如下:

import re

text = "你们好 Hello"

p = r"\w+"
# 设置编译标志为 Unicode 编码
regex = re.compile(p, re.U)
# search() 方法匹配 “你们好Hello” 字符串
m = regex.search(text)
print(m)
# match() 方法也可匹配 “你们好Hello” 字符串
m = regex.match(text)
print(m)

# 设置编译标志为 ASCII 编码
regex = re.compile(p, re.A)
# 用 search() 方法匹配 “Hello” 字符串
m = regex.search(text)
print(m)
# match() 方法不可匹配
m = regex.match(text)
print(m)

执行结果:

<re.Match object; span=(0, 3), match='你们好'>
<re.Match object; span=(0, 3), match='你们好'>
<re.Match object; span=(4, 9), match='Hello'>
None
13.6.2.2 忽略大小写

默认情况下正则表达式引擎对大小写是敏感的,但有时在匹配过程中需要忽略大小写 ,可以通过编译标志 re.IGNORECASE(或re.I)实现。

示例代码如下:

import re

# 定义正则表达式
p = r"(java).*(python)"
# 编译正则表达式,设置编译参数 re.I 忽略大小写
regex = re.compile(p, re.I)

m = regex.search("I like Java and Python.")
print(m)

m = regex.search("I like JAVA and Python.")
print(m)

m = regex.search("I like java and Python.")
print(m)

执行结果:

<re.Match object; span=(7, 22), match='Java and Python'>
<re.Match object; span=(7, 22), match='JAVA and Python'>
<re.Match object; span=(7, 22), match='java and Python'>

由于忽略了大小写,代码中三个 search() 方法都能找到匹配的字符串。

13.6.2.3 点元字符匹配换行符

默认情况下正则表达式引擎中点 “.” 元字符可以匹配除换行符外的任何字符,但是有时需要点 “.” 元字符也能匹配换行符,这可以通过编译标志re.DOTALL(或 re.S)实现。

示例代码如下:

import re

p = r".+"

# 编译正则表达式时没有设置编译标志
regex = re.compile(p)
# 配结果是 "Hello" 字符串
# 因为正则表达式引擎遇到换行符 "\n" 时
# 认为它是不匹配的,就停止查找
m = regex.search("Hello\nWorld.")
print(m)

# 编译了正则表达式,并设置编译标志 re.DOTALL
regex = re.compile(p, re.DOTALL)
# 匹配结果是 "Hello\nWorld" 字符串
# 因为正则表达式引擎遇到换行符 "\n" 时
# 认为它是匹配的,会继续查找
m = regex.search("Hello\nWorld.")
print(m)

执行结果:

<re.Match object; span=(0, 5), match='Hello'>
<re.Match object; span=(0, 12), match='Hello\nWorld.'>
13.6.2.4 多行模式

编译标志 re.MULTILINE(或 re.M)可以设置为多行模式,多行模式对于元字符 ^$ 行为会产生影响。
默认情况下 ^$ 匹配字符串的开始和结束,而在多行模式下 ^$ 匹配任意一行的开始和结束。

示例代码如下:

import re

# 定义了正则表达式 ^World
# 匹配 World 开头的字符串
p = r"^World"

# 进行编译时并没有设置多行模式
regex = re.compile(p)
# 代码 "Hello\nWorld" 字符串是不匹配的
# 虽然 "Hello\nWorld" 字符串事实上是两行
# 但默认情况 ^World 只匹配字符串的开始
m = regex.search("Hello\nWorld.")
print(m)

# 重新编译了正则表达式
# 此时设置了编译标志 re.M 开启多行模式
# 在多行模式下 ^ 和 $ 匹配字符串任意一行的开始和结束
regex = re.compile(p, re.M)
# 匹配 World 字符串
m = regex.search("Hello\nWorld.")
print(m)

执行结果:

None
<re.Match object; span=(6, 11), match='World'>
13.6.2.5 详细模式

编译标志 re.VERBOSE(或 re.X)可以设置详细模式。
详细模式 下可以在正则表达式中添加注释,可以有空格和换行,这样编写的正则表达式非常便于阅读。

示例代码如下:

import re

# 定义的正则表达式原本是 (java).*(python)
# 现在写成多行表示,其中还有注释和空格等内容
# 如果没有设置详细模式,这样的正则表达式会抛出异常
# 由于正则表达式中包含了换行等符号
# 所以需要使用双重单引号或三重双引号括起来
# 而不是使用原始字符串
p = """(java)
       .*
       (python)
    """

# 编译正则表达式时,设置了两个编译标志 re.I 和 re.VERBOSE
# 当需要设置多编译标志时,编译标志之间需要位或运算符 "|"
regex = re.compile(p, re.I|re.VERBOSE)

m = regex.search("I like Java and Python.")
print(m)

m = regex.search("I like JAVA and Python.")
print(m)

m = regex.search("I like java and Python.")
print(m)

执行结果:

<re.Match object; span=(7, 22), match='Java and Python'>
<re.Match object; span=(7, 22), match='JAVA and Python'>
<re.Match object; span=(7, 22), match='java and Python'>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值