飞道的博客

Python 内置模块之 re 库,一文搞定正则表达式初阶用法,滚雪球学 Python 第 13 篇

435人阅读  评论(0)

橡皮擦,一个逗趣的互联网高级网虫。新的系列,让我们一起 Be More Pythonic

已完成的文章清单

  1. 滚雪球学 Python 第二轮开启,进阶之路,列表与元组那些事儿
  2. 说完列表说字典,说完字典说集合,滚雪球学 Python
  3. 关于 Python 中的字符串,我在补充两点,滚雪球学 Python
  4. 列表推导式与字典推导式,滚雪球学 Python
  5. 滚雪球学 Python 之 lambda 表达式
  6. 滚雪球学 Python 之内置函数:filter、map、reduce、zip、enumerate
  7. Python 中级知识之装饰器,滚雪球学 Python
  8. 滚雪球学 Python 之闭包操作,本系列第 8 篇文章
  9. 滚雪球学 Python 之怎么玩转时间和日期库
  10. 滚雪球学 Python 之作用域下的 global 和 nonlocal 关键字
  11. 哈希吧,滚雪球学 Python 哈希表与可哈希对象
  12. 滚雪球学 Python 之内置 random 模块

十三、Python 内置模块之 re 库,一文搞定正则表达式初阶用法

13.1 re 库的应用

re 库是 Python 中处理正则表达式的标准库,本篇博客介绍 re 库的同时,会简单介绍一下正则表达式语法,如果想深入学习正则表达式,还需要好好下一番功夫。

13.1.1 正则表达式语法

正则表达式语法由字符和操作符构成,初期阶段掌握下述这些内容即可。

操作符 说明 例子
. 任何单个字符,极少不能匹配
[] 字符集,对单个字符给出取值范围 [abc] 表示匹配 a、b、c,[a-z] 表示 a 到 z 单个字符
[^] 非字符集,对单个字符给出排除范围 [^abc] 表示匹配 非 a、非 b、非 c 的单个字符
* 前一个字符 0 次或无限次扩展 abc* 表示 ab、abc、abcc、abccc 等
+ 前一个字符 1 次或无限次扩展 abc+ 表示 abc、abcc、abccc 等
? 前一个字符 0 次或 1 次 abc? 表示 ab、abc
| 左右表达式任意一个 abc|def 表示 abc 或者 def
{m} 扩展前 1 个字符 m 次 ab{2}c,表示 abbc
{m,n} 扩展前 1 个字符 m 到 n 次 ab{1,2}c,表示 abc、abbc
^ 匹配字符串开头 ^abc 表示 abc 在字符串开头
$ 匹配字符串结尾 abc$ 表示 abc 在字符串结尾
() 分组标记,内部仅能使用 | 操作符 (abc) 表示 abc,(a
\d 数字,等价于 [0-9]
\w 字符,等价于 [A-Za-z0-9]

以上表示仅仅为正则表达最基础部分内容,如果希望深入研究正则表达式,建议寻找更加全面的资料进行学习,本文只做药引。

13.1.2 re 库基本用法

re 库主要函数如下:

  • 基础函数:compile
  • 功能函数:searchmatchfindallsplitfinditersub

在正式学习之前,先了解一下原生字符串。

在 Python 中,表示原生字符串,需要在字符串前面加上 r
例如 my_str = 'i'am xiangpica' 在程序中会直接报错,如果希望字符串中 ' 可以正常运行,需要加上转移字符 \,修改为 my_str = 'i\'am xiangpica'
但这样结合上文正则表达式中的操作符,就会出现问题,因为 \ 在正则表达式中是有真实含义的,如果你使用 re 库去匹配字符串中的 \,那需要使用 4 个反斜杠,为了避免这种情况出现,引入了原生字符串概念。

# 不使用原生字符串的正则表达式  "\\\\"
# 使用原生字符串的正则表达式 r"\\"

在后文会有实际的应用。

接下来在学习一个案例,例如下述代码:

my_str='C:\number'

print(my_str)
C:
umber

本段代码的输出效果如下,\n 被解析成了换行,如果想要屏蔽这种现象,使用 r 即可:

my_str=r'C:\number'

print(my_str)

输出 C:\number

13.2 re 库相关函数说明

13.2.1 re.search 函数

该函数用于,在字符串中搜索正则表达式匹配到的第一个位置的值,返回 match 对象。
函数原型如下:

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

需求:在字符串 梦想橡皮擦 good good 中匹配 橡皮擦

import re
my_str='梦想橡皮擦 good good'
pattern = r'橡皮擦'

ret = re.search(pattern,my_str)
print(ret)

返回结果:<re.Match object; span=(2, 5), match='橡皮擦'>

search 函数的第三个参数 flags 表示正则表达式使用时的控制标记。

  • re.Ire.IGNORECASE:忽略正则表达式的大小写;
  • re.Mre.MULTILINE:正则表达式中的 ^ 操作符能够将给定字符串的每行当做匹配的开始;
  • re.Sre.DOTALL:正则表达式中的 . 操作符能够匹配所有字符。

最后将匹配到的字符串进行输出,使用下述代码即可实现。

import re
my_str = '梦想橡皮擦 good good'
pattern = r'橡皮擦'

ret = re.search(pattern, my_str)
if ret:
    print(ret.group(0))

13.2.2 re.match 函数

该函数用于在目标字符串开始位置去匹配正则表达式,返回 match 对象,未匹配成功返回 None,函数原型如下:

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

一定要注意是目标字符串开始位置。

import re
my_str = '梦想橡皮擦 good good'
pattern = r'梦' # 匹配到数据
pattern = r'good' # 匹配不到数据

ret = re.match(pattern, my_str)
if ret:
    print(ret.group(0))

re.matchre.search 方法都是一次最多返回一个匹配对象,如果希望返回多个值,可以通过在 pattern 里加括号构造匹配组返回多个字符串。

13.2.3 re.findall 函数

该函数用于搜索字符串,以列表格式返回全部匹配到的字符串,函数原型如下:

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

测试代码如下:

import re
my_str = '梦想橡皮擦 good good'
pattern = r'good'
ret = re.findall(pattern, my_str)
print(ret)

13.2.4 re.split 函数

该函数将一个字符串按照正则表达式匹配结果进行分割,返回一个列表。
函数原型如下:

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

re.split 函数进行分割的时候,如果正则表达式匹配到的字符恰好在字符串开头或者结尾,返回分割后的字符串列表首尾都多了空格,需要手动去除,例如下述代码:

import re
my_str = '1梦想橡皮擦1good1good1'

pattern = r'\d'

ret = re.split(pattern, my_str)

print(ret)

运行结果:

['', '梦想橡皮擦', 'good', 'good', '']

切换为中间的内容,则能正确的分割字符串。

import re
my_str = '1梦想橡皮擦1good1good1'

pattern = r'good'

ret = re.split(pattern, my_str)

print(ret)

如果在 pattern 中捕获到括号,那括号中匹配到的结果也会在返回的列表中。

import re
my_str = '1梦想橡皮擦1good1good1'

pattern = r'(good)'

ret = re.split(pattern, my_str)

print(ret)

运行结果,你可以对比带括号和不带括号的区别进行学习:

['1梦想橡皮擦1', 'good', '1', 'good', '1']

maxsplit 参数表示最多进行分割次数, 剩下的字符全部返回到列表的最后一个元素,例如设置匹配 1 次,得到的结果是 ['1梦想橡皮擦1', '1good1']

13.2.5 re.finditer 函数

搜索字符串,并返回一个匹配结果的迭代器,每个迭代元素都是 match 对象。函数原型如下:

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

测试代码如下:

import re
my_str = '1梦想橡皮擦1good1good1'

pattern = r'good'

# ret = re.split(pattern, my_str,maxsplit=1)
ret =re.finditer(pattern, my_str)
print(ret)

13.2.6 re.sub 函数

在一个字符串中替换被正则表达式匹配到的字符串,返回替换后的字符串,函数原型如下:

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

其中 repl 参数是替换匹配字符串的字符串,count 参数是匹配的最大替换次数。

import re
my_str = '1梦想橡皮擦1good1good1'

pattern = r'good'

ret = re.sub(pattern, "nice", my_str)
print(ret)

运行之后,得到替换之后的字符串:

1梦想橡皮擦1nice1nice1

13.2.7 re 库其它函数

其它比较常见的函数有:re.fullmatch()re.subn()re.escape(),更多内容可以查阅 官方文档,获取一手资料。

13.3 re 库的面向对象写法

上文都是函数式写法,re 库可以采用面向对象的写法,将正则表达式进行编译之后,多次操作。核心用到的函数是 re.compile

该函数原型如下:

regex = re.compile(pattern,flags=0)

其中 pattern 是正则表达式字符串或者原生字符串。

测试代码如下:

import re
my_str = '1梦想橡皮擦1good1good1'
# 正则对象
regex = re.compile(pattern = r'good')

ret = regex.sub("nice", my_str)
print(ret)

上述代码将正则表达式编译为一个正则对象,后面在 regex.sub 函数中就不需要在写正则表达式了,使用时,只需要将编译好的 regex 对象替换所有的 re 对象,再去调用对应的方法。

13.4 re 库的 match 对象

使用 re 库匹配字符串之后,会返回 match 对象,该对象具备以下属性和方法。

13.4.1 match 对象的属性

  • .string:待匹配的文本;
  • .re:匹配时使用的 pattern 对象;
  • .pos:正则表达式搜索文本的开始位置;
  • .endpos:正则表达式搜索文本的结束位置。

测试代码如下:

import re
my_str = '1梦想橡皮擦1good1good1'

regex = re.compile(pattern = r'g\w+d')

ret = regex.search(my_str)
print(ret)
print(ret.string)
print(ret.re)
print(ret.pos)
print(ret.endpos)

结果输出:

<re.Match object; span=(7, 16), match='good1good'>
1梦想橡皮擦1good1good1
re.compile('g\\w+d')
0
17

13.4.2 match 对象的方法

  • .group(0):获取匹配后的字符串;
  • .start():匹配字符串在原始字符串的开始位置;
  • .end():匹配字符串在原始字符串的结尾位置;
  • .span():返回(.start(),.end())

因为内容比较简单,具体代码不再展示。

13.5 这篇博客的总结

本篇博客学习了 Python 中 re 库的知识点,重点在 re 库中的各个函数,对正则表达式未做过多说明,希望对你有所帮助。

相关阅读

  1. Python 爬虫 100 例教程,超棒的爬虫教程,立即订阅吧
  2. Python 爬虫小课,精彩 9 讲

今天是持续写作的第 101 / 200 天。
如果你想跟博主建立亲密关系,可以关注同名公众号 梦想橡皮擦,近距离接触一个逗趣的互联网高级网虫。
博主 ID:梦想橡皮擦,希望大家点赞评论收藏


转载:https://blog.csdn.net/hihell/article/details/114648366
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场