python|exm5-3re模块,正则表达式概念介绍|match()、search()、findall()、sub()、split()

发布于:2025-03-21 ⋅ 阅读:(16) ⋅ 点赞:(0)

一、re模块和正则表达式

1.re模块

        re模块是 Python 中用于处理正则表达式的标准库模块。它提供了丰富的函数和方法,用于字符串的匹配、查找、替换和分割等操作。以下是re模块的常用函数和方法及其详细说明

2. 正则表达式

        正则表达式(Regular Expression,简称 regex 或 regexp)是一种用于 匹配字符串模式 的强大工具。它通过定义特定的语法规则,可以快速查找、替换或提取符合某种模式的文本

        正则表达式广泛应用于文本处理、数据验证、日志分析、搜索引擎等领域。几乎所有编程语言(如 Python、Java、JavaScript 等)都支持正则表达式。

2.1 正则表达式基本组成

正则表达式由 普通字符 和 元字符 组成:

  • 普通字符:如字母、数字、空格等,直接匹配自身。

  • 元字符:具有特殊含义的字符,用于定义匹配规则。

2.2 常用元字符

        原字符较多,很难记忆,大家可以见过表格保存下来,方便做参考。

        我将在下面的函数中应用这些元字符帮助大家加深了解。

元字符 描述 示例
. 匹配任意字符(除换行符外) a.c 匹配 abcaac 等
\d 匹配数字(0-9) \d+ 匹配 123456 等
\w 匹配字母、数字或下划线 \w+ 匹配 hello_123
\s 匹配空白字符(空格、制表符等) \s+ 匹配 (空格)
^ 匹配字符串的起始位置 ^abc 匹配以 abc 开头的字符串
$ 匹配字符串的结束位置 abc$ 匹配以 abc 结尾的字符串
* 匹配前一个字符 0 次或多次 a* 匹配 aaaaaa 等
+ 匹配前一个字符 1 次或多次 a+ 匹配 aaaaaa 等
? 匹配前一个字符 0 次或 1 次 a? 匹配 a 或空字符串
{n} 匹配前一个字符恰好 n 次 a{3} 匹配 aaa
{n,} 匹配前一个字符至少 n 次 a{2,} 匹配 aaaaa 等
{n,m} 匹配前一个字符 n 到 m 次 a{2,4} 匹配 aaaaa 等
[] 匹配括号内的任意字符 [abc] 匹配 ab 或 c
` ` 匹配多个模式中的任意一个 `a b匹配ab`
() 分组,捕获匹配的子串 (abc)+ 匹配 abcabcabc

2.3 正则表达式的优缺点

优点
  • 强大灵活:可以匹配复杂的字符串模式。

  • 高效:适合处理大量文本数据。

  • 通用性:几乎所有编程语言都支持正则表达式。

缺点
  • 学习曲线陡峭:语法复杂,初学者需要时间掌握。

  • 可读性差:复杂的正则表达式难以理解和维护。

  • 性能问题:某些复杂的正则表达式可能导致性能下降。

2.4 正则表达式在线测试工具: 

3. re模块函数下flags 的含义:控制匹配行为

        在 re.match(pattern,string,flags=0) 中,flags是一个可选参数,用于控制正则表达式的匹配行为。它可以通过设置不同的标志位来调整正则表达式的匹配方式,例如忽略大小写、多行匹配等。

flags参数的值可以是以下常量之一,或者通过按位或(|)组合多个常量:


常用 flags 常量

常量名 描述
re.IGNORECASE 或 re.I 忽略大小写匹配。例如,A 和 a 会被视为相同字符。
re.MULTILINE 或 re.M 多行模式。使 ^ 和 $ 分别匹配每一行的开头和结尾,而不是整个字符串的开头和结尾。
re.DOTALL 或 re.S 使 . 匹配任意字符,包括换行符(默认情况下 . 不匹配换行符)。
re.VERBOSE 或 re.X 允许在正则表达式中添加注释和空白符,使其更易读。
re.ASCII 或 re.A 使 \w\W\b\B\s\S 仅匹配 ASCII 字符。
re.LOCALE 或 re.L 使 \w\W\b\B\s\S 依赖于当前区域设置(不推荐使用)。
re.UNICODE 或 re.U 使 \w\W\b\B\s\S 匹配 Unicode 字符(Python 3 默认行为)。

二、函数表达式

1. re.match()

re.match(pattern, string, flags=0)
  • 功能:从字符串的起始位置匹配正则表达式

  • 返回值:如果匹配成功,返回 Match 对象;否则返回 None

import re # 导入  re(regular expressions)
pattern='\d\.\d+' # +限定符,\d 0-9的数字出现一次或多次
# '\d\.\d+'--> 一个数字.多个数字--> 3.13
s='I study python 3.13 every day' # 待匹配字符串
match=re.match(pattern,s,re.I)    # 用pattern中的元字符,匹配s中的元素,re.I忽略大小写
print(match) # None
s2='3.13 python I study every day'
match2=re.match(pattern,s2,re.I)
print(match2)   # <re.Match object; span=(0, 4), match='3.13'>
print('匹配的起始值是:',match2.start()) # 0
print('匹配值的结束位置:',match2.end()) # 4
print('匹配区间的位置元素:',match2.span()) # (0,4)  span n.跨度;跨越;持续时间;
print('待匹配的字符串:',match2.string) # 3.13 python I study every day
print('匹配的数据:',match2.group()) # 3.13

输出结果: 

None
<re.Match object; span=(0, 4), match='3.13'>
匹配的起始值是: 0
匹配值的结束位置: 4
匹配区间的位置元素: (0, 4)
待匹配的字符串: 3.13 python I study every day
匹配的数据: 3.13

2. re.search() 

  • 功能:在字符串中查找第一个匹配正则表达式的位置

  • 返回值:如果匹配成功,返回 Match 对象;否则返回 None

import re
pattern='\d\.\d+'
s='I study Python3.13 every day Python2.2 I love you'
match=re.search(pattern,s)
print(match) # <re.Match object; span=(14, 18), match='3.13'>

s2='4.2345 sdf gb yju '
s3='dfsd hyt rtu yr'
match2=re.search(pattern,s2)
match3=re.search(pattern,s3)

print(match2) # <re.Match object; span=(0, 6), match='4.2345'>
print(match3) # None

print(match.group()) # match匹配的数据    3.13
print(match2.group()) # match2匹配的数据  4.2345

3. re.findall()

  • 功能:查找字符串中所有匹配正则

    表达式的子串,并返回一个列表。

  • 返回值:匹配的子串列表。

import re
pattern='\d\.\d+'
s='I study Python3.13 every day Python2.2 I love you'
s2='3.3 asdf serg awert '
s3='asdf serg awert'
# re.findall() 返回列表
lst=re.findall(pattern,s)
lst2=re.findall(pattern,s2)
lst3=re.findall(pattern,s3)
print(lst)
print(lst2)
print(lst3)

 输出结果:

['3.11', '2.2']
['3.3']
[]

4. re.finditer() 

  • 功能:查找字符串中所有匹配正则表达式的子串,并返回一个迭代器。

  • 返回值:包含 Match 对象的迭代器。

    import re
    pattern='\d\.\d+'
    s='I study Python 3.11 every day Python 2.2 I love you'
    match=re.finditer(pattern,s)
    print(f'match的类型是{type(match)},输出的是{match}')
    # match的类型是<class 'callable_iterator'>,输出的是<callable_iterator object at 0x0000025D1C94E740>
    for item in match:
        print(f'item的类型为:{type(item)},输出的是{item.group()}')
    # item的类型为:<class 're.Match'>,输出的是3.11
    # item的类型为:<class 're.Match'>,输出的是2.2

    输出结果:

    match的类型是<class 'callable_iterator'>,输出的是<callable_iterator object at 0x000002A3811BEB90>
    item的类型为:<class 're.Match'>,输出的是3.11
    item的类型为:<class 're.Match'>,输出的是2.2

5. re.sub() + 逐步替换

  • 功能:将字符串中匹配正则表达式的子串替换为指定内容。

  • 返回值:替换后的字符串。

re.sub(pattern, repl, string, count=0, flags=0)
"""
count 参数用于控制 re.sub() 的替换次数。
默认值为 0,表示替换所有匹配的子串。
通过设置 count=n,可以限制最多替换前 n 个匹配的子串。
在实际应用中,count 可以用于限制替换次数或实现逐步替换的逻辑。
"""
import re
pattern='黑客|破解|反爬'
s='我想学习Python,想破解一些视频,Python可以实现无底线反爬吗?'
new_s=re.sub(pattern,'XXX',s) # count默认为0,将全部替换,count=-1 == count=0
new_s2=re.sub(pattern,'XXX',s,1)
print(new_s)  # 我想学习Python,想XXX一些视频,Python可以实现无底线XXX吗?
print(new_s2) # 我想学习Python,想XXX一些视频,Python可以实现无底线反爬吗?
# 通过循环和count实现逐步替换
print('-'*20+'逐步替换'+'_'*20)
"""
# while '黑客' or '反爬' or '破解' in s: 错误写法
'黑客' or '反爬' or '破解' in s 的写法是错误的。or 是逻辑运算符,
它会先计算 '黑客' 的真值,然后计算 '反爬' 的真值,最后计算 '破解' in s 的真值。
由于非空字符串 '黑客' 和 '反爬' 的真值始终为 True,因此整个条件表达式的结果始终为 True,导致循环永远不会停止。
"""
while '黑客' in s or '反爬' in s or '破解' in s:
    s=re.sub(pattern,'XXX',s,count=1)
    print(s)

输出结果:

我想学习Python,想XXX一些视频,Python可以实现无底线XXX吗?
我想学习Python,想XXX一些视频,Python可以实现无底线反爬吗?
--------------------逐步替换____________________
我想学习Python,想XXX一些视频,Python可以实现无底线反爬吗?
我想学习Python,想XXX一些视频,Python可以实现无底线XXX吗?

6. re.split()

  • 功能:根据正则表达式分割字符串。

  • 返回值:分割后的字符串列表。

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

在re.split(pattern,string,maxsplit,flags=0)中, maxsplit 是一个可选参数,用于指定 最大分割次数。它的默认值为 0,表示不限制分割次数,即尽可能多地分割字符串。 

s2='https://www.baidu.com/s?wd=zj&rsv_spt=1' # 一个随便找的网址
pattern2='[?|&]' # [] 包括括号内的任意字符
lst1=re.split(pattern2,s2,2)
lst2=re.split(pattern2,s2,1)
print(lst1)
print(*lst1,sep='')  # 解包操作,可以去掉列表的括号
print(lst2)

输出结果:

['https://www.baidu.com/s', 'wd=zj', 'rsv_spt=1']
https://www.baidu.com/swd=zjrsv_spt=1
['https://www.baidu.com/s', 'wd=zj&rsv_spt=1']

总结:

正则表达式应用较为复杂,需要对相关函数、元字符进行更加深入的了解。

若有错误,敬请批评指正