前言

本篇主要讲调用正则表达式RE模块内置的方法(函数)来开发,需了解元字符功能的可查看文章:Python3 正则表达式使用(1)

正则表达式可分为"解释型"和"编译型"两种,在开发中,通常都会将正则进行编译处理,这样可以使得程序执行的速度更快,效率更高。

RE模块提供了一个compile()方法,它可以将你的REstring编译成对象,然后再使用这个对象来进行匹配。

例如:

>>> import re   # 导入re 模块
>>> a = r'a..b'    # 定义正则
>>> zz = re.compile(a)    # 编译正则
>>> zz
re.compile('a..b')
>>>

PS : 在Python2 中,zz返回的是一个对象信息,如下:
<_sre.SRE_Pattern object at 0xb74de2c0>

正则编译实例

实例如下:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import re
r = r'\d{4}-?\d{7}'     # 定义一个匹配固定电话号码的正则
tel = re.compile( r )     # 编译这个正则
print( tel.findall('0306-1234567') )    # 调用并输出

运行输出:
['0306-1234567']

解释:调用该正则时只需将编译好的对象 tel 去访问 findall() 这个方法即可!

标志参数

在 RE中有很多的方法都可以接受标志参数 ,通常使用这些参数实现一些不同的特殊功能。
当使用 help() 查询一个方法的使用资料时,如果其语法中有 flag = 0 这个参数的时候,都表示它是一个可选的标志参数。

常用的标志参数:

参数功能
re.I使匹配的字符串不区分大小写.
re.S使 元字符"." 匹配包括换行在内的所有字符. 如:\n \r \t .....
re.M多行匹配(影响 ' 行首 ^ ' 和 '行尾 $ ').
re.L做本地化识别( local-aware )匹配.
re.X使存在 分行的正则表达式 也能正确匹配(目的:使正则更清晰).

实例1:
功能: 编译时加入 re.I 参数,使得匹配的字符串不区分大小写。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import re
csvt_re = re.compile(r'csvt',re.I)  # 添加 re.I 属性
print( csvt_re.findall('csvt') )    # 全小写
print( csvt_re.findall('CSVT') )    # 全大写
print( csvt_re.findall('CsVt') )    # 大小写混合

运行输出:

['csvt']
['CSVT']
['CsVt']

实例2:
功能: 编译时加入 re.M 参数,实现字符串多行匹配。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import re

#### 定义一个分行存储的字符串 ####
s = '''
hello world
study python
hello make
study java
hello python
learn end
'''
#### 定义正则 ####
r1 = r'^study' # 匹配各行行首的 ' study '
r2 = r'python$' # 匹配各行行尾的 ' python'

#### 行首匹配差异 ####
print( re.findall(r1,s) )
print( re.findall(r1,s,re.M) )

#### 行尾匹配差异 ####
print( re.findall(r2,s) )
print( re.findall(r2,s,re.M) )

运行输出:
[]
['study', 'study']
[]
['python', 'python']

分析: 当使用换行来存储一个字符串时,各行之间的是存在一个 \n 字符的(交互模式下可看到),所以在匹配时只有加入 re.M 属性才可将其匹配出来。

实例3:
功能: 编译时加入 re.X 参数,使" 分行正则 "的能正确匹配。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import re

#### 定义(区号+ 电话)正则 ####
r = r'''
\d{4}
-?
\d{7}
'''

print( re.findall(r,'0360-1234567') )
print( re.findall(r,'0360-1234567',re.X) )

运行输出:
[]
['0360-1234567']

RE中常用的方法

RegexObject 实例有一些方法和属性,完整的列表可查阅 Python Library Reference 。

方法功能
match()从起始位置开始匹配,内容存在则返回 MatchObject 实例,否则返回 None
search()查找字符串中是否有 RE 匹配的内容,有则返回 SearchObject 实例,否则返回 None
findall()查找 RE 匹配的内容,并将其所有内容以列表形式返回
finditer()查找 RE 匹配的全部内容,并将其以 迭代器 形式返回
sub()根据正则,替换源字符串中的某些字符
spilt()根据正则,对源字符串进行切割

使用以上这些方法的时候同样可以加入可选的 "标志参数" 进行灵活使用!

使用以上前4个方法的时候,当有值匹配时返回的是一个 对象信息,如果需要获取相应的" 值 "或者" 信息 ",需要用到以下的这些方法来获取。

MatchObject 实例方法:

方法功能
group()返回 RE 匹配的字符串值
start()返回 匹配开始的位置
end()返回 匹配结束的位置
span()以元组形式返回 匹配( 开始,结束 ) 的位置

具体操作,参考 search() 这个方法的使用!

Match( ) 方法

实例如下:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import re
test = re.compile(r'hello')
print( test.match('hello world') )      # 位于 起始 位置
print( test.match('python hello') )     # 位于 末端 位置

运行输出:
<_sre.SRE_Match object; span=(0, 5), match='hello'>
None

可见在程序进行内容匹配时返回的是一个 对象信息,而并非返回匹配对应的字符串。
下面介绍如何获取这个对象的值,实例如下:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import re
test = re.compile(r'hello')
val = test.match('hello world')      # 把 把MatchObject 赋给 变量 val
print( val.group() )    # 通过 val 去访问 group 这个方法,获取re匹配后相应的值

运行输出:
hello

match() 在使用时通常是用于判断是否有值, 所以通常会结合条件判断语句来使用!
注意:当 re 匹配不成功(即返回为None)时,以上获取值的这个方法时违规的。

Search( ) 方法

实例如下:

print( "匹配后的值:" )
print( var1.group() )
print( var2.group() )
print( var3.group() )

print( "匹配时,字符串的起始位置:" )
print( var1.start() )
print( var2.start() )
print( var3.start() )

print( "匹配时,字符串的结束位置:" )
print( var1.end() )
print( var2.end() )
print( var3.end() )

print( "匹配时,字符串的(起始/结束)位置:" )
print( var1.span() )
print( var2.span() )
print( var3.span() )

运行输出:
查找是否匹配正则:
<_sre.SRE_Match object at 0xb74de528>
<_sre.SRE_Match object at 0xb74deaa0>
<_sre.SRE_Match object at 0xb74dee20>
匹配后的值:
hello
hello
hello
匹配时,字符串的起始位置:
0
6
6
匹配时,字符串的结束位置:
5
11
11
匹配时,字符串的(起始/结束)位置:
(0, 5)
(6, 11)
(6, 11)

sub ( )方法

语法格式:

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

参数说明:

  • pattern :正则表达式
  • repl : 被替换字符串
  • string :字符串

实例如下:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import re

ti = re.compile('h...o') # 制定正则

### 将字符串中符合 'h...o' 格式的子串替换成 ' nihao '
print( re.sub(ti,'nihao','hello world heeeo python') )

运行输出:
nihao world nihao python

spilt( ) 方法

语法格式:

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

参数说明:

  • pattern :正则表达式
  • string :字符串

实例如下:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import re

qg = re.compile(r'[\+\-\*/]')    # 制定 + - * / 正则

print( re.split(qg,'a+b-c*d/e') )    # 匹配正则切割输出

运行输出:
['a', 'b', 'c', 'd', 'e']

正则优先返回值

在 RE 中,定义正则的时候如果使用到 '元组( )' 时,优先返回元组中的数据。

实例如下:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import re

### 正则中使用元组 ###
web = r'www\.\w+(\.com|.net)'

print( re.findall(web,'www.taobao.com') )   # 匹配
print( re.findall(web,'www.csdn.net') )     # 匹配
print( re.findall(web,'www.test.org') )     # 不匹配

运行输出:
['.com']
['.net']
[]

【分析】
1、通过匹配和不匹配字符串输出,可以知道该匹配规则是使用全局匹配的。
2、正则中可以使用 或 | 关系符,表示多选。
3、通过返回值可以看到 findall( ) 函数优先返回 元组中匹配的数据,

提示:如果需要获取完整的值,可以使用 match() 方法获取对象,然后再使用 group() 函数获取完整值即可。

更多学习教程请访问:Python3 学习教程目录索引

最后修改:2022 年 06 月 08 日
如果觉得我的文章对你有用,请随意赞赏