Python 正则表达式模块 re

发布于:2025-03-15 ⋅ 阅读:(57) ⋅ 点赞:(0)

Python 正则表达式模块 re

flyfish

一、正则表达式基础

1. 什么是正则表达式?

正则表达式(Regular Expression, RE)是一种用于匹配、查找和替换文本模式的工具,由普通字符(如字母、数字)和特殊字符(元字符)组成。

2. 常用元字符
元字符 说明 示例
. 匹配任意单个字符(除换行符) a.cabc, adc
\w 匹配字母、数字或下划线 \w+hello123
\d 匹配数字 \d{3}123
\s 匹配空白字符(空格、制表符等) \s+ → 多个空格
* 匹配前一个字符零次或多次 ab*a, ab, abb
+ 匹配前一个字符一次或多次 ab+ab, abb
? 匹配前一个字符零次或一次 ab?aab
^ 匹配字符串开头 ^abc → 以abc开头
$ 匹配字符串结尾 abc$ → 以abc结尾

二、Python 正则表达式模块 re

1. 模块导入
import re
2. 常用函数
函数名 作用描述
re.compile() 编译正则表达式,提高重复使用效率
re.match() 从字符串开头匹配模式
re.search() 在字符串任意位置搜索模式
re.findall() 查找所有匹配项,返回列表
re.finditer() 查找所有匹配项,返回迭代器
re.sub() 替换匹配项
re.subn() 替换匹配项并返回替换次数
re.split() 按模式分割字符串
re.fullmatch() 要求整个字符串完全匹配模式

三、核心功能详解

1. 匹配操作
  • re.match()(从开头匹配)
    match = re.match(r'hello', 'hello world')
    print(match.group())  # 输出: hello
    

match = re.search(r'```json(.*?)```', content, re.DOTALL)

re.search() 函数

re.search(pattern, string, flags=0)re 模块中的一个函数,用于在字符串 string 中搜索第一个与模式 pattern 匹配的子字符串。如果找到匹配项,则返回一个匹配对象;如果没有找到,则返回 None

  • pattern:要搜索的正则表达式模式。
  • string:要在其中进行搜索的字符串,这里是 content
  • flags:可选参数,用于指定正则表达式的匹配模式。这里使用了 re.DOTALL
正则表达式模式 r'```json(.*?)```'
  • r:在字符串前面加上 r 表示这是一个原始字符串。在原始字符串中,反斜杠 \ 不会被当作转义字符处理,这样可以避免在编写正则表达式时出现过多的转义字符,提高代码的可读性。
  • json ````:这是一个普通的字符串,表示匹配以 json ````开头的文本。
  • (.*?):这是一个捕获组,用于匹配任意字符(除换行符外,除非使用了 re.DOTALL 标志)。
    • .:匹配除换行符外的任意单个字符。
    • *:表示前面的字符(即 .)可以出现零次或多次。
    • ?:在 * 后面加上 ? 表示非贪婪匹配。贪婪匹配会尽可能多地匹配字符,而非贪婪匹配会尽可能少地匹配字符。例如,如果字符串中有多个 json...代码块,非贪婪匹配会只匹配到第一个 ```````````就停止。
  • :表示匹配以 结尾的文本。
re.DOTALL 标志

re.DOTALLre 模块中的一个标志,它会改变 . 的匹配行为。默认情况下,. 不匹配换行符,但使用 re.DOTALL 后,. 可以匹配包括换行符在内的任意字符。这意味着代码块中可以包含换行符,能够正确匹配多行的 JSON 代码块。

  • re.search()(全局搜索)
    search = re.search(r'world', 'hello world')
    print(search.group())  # 输出: world
    
2. 查找所有匹配项
  • re.findall()
    numbers = re.findall(r'\d+', 'a123b456c')
    print(numbers)  # 输出: ['123', '456']
    
3. 替换操作
  • re.sub()
    text = re.sub(r'\d+', 'X', 'a123b456c')
    print(text)  # 输出: aXbXc
    
4. 分割字符串
  • re.split()
    parts = re.split(r'\s+', 'hello   world')
    print(parts)  # 输出: ['hello', 'world']
    

四、捕获组与 group() 方法

1. 基本用法
pattern = r'(\d{4})-(\d{2})-(\d{2})'
date_str = '2025-03-11'
match = re.search(pattern, date_str)

print(match.group(0))  # 完整匹配结果 → '2025-03-11'
print(match.group(1))  # 第一个捕获组 → '2025'
print(match.group(2))  # 第二个捕获组 → '03'
print(match.group(3))  # 第三个捕获组 → '11'
2. 查看捕获组数量
  • 使用 groups()
    groups = match.groups()
    print(len(groups))  # 输出: 3
    
  • 命名捕获组(使用 groupdict()
    pattern = r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'
    match = re.search(pattern, date_str)
    print(match.groupdict())  # 输出: {'year': '2025', 'month': '03', 'day': '11'}
    

五、re.match vs re.search

基本概念对比
  • re.match:该函数会从字符串的起始位置开始尝试匹配正则表达式模式。如果字符串的起始位置不符合模式,即使字符串的其他部分存在匹配内容,re.match 也会返回 None。也就是说,它要求模式必须从字符串的第一个字符开始匹配成功。
  • re.search:此函数会在整个字符串中进行搜索,查找与正则表达式模式匹配的第一个位置。只要字符串中存在一处符合模式的内容,re.search 就会返回一个匹配对象。
详细示例对比
示例 1:模式在字符串起始位置匹配
import re

# 定义字符串和模式
pattern = r'hello'
string = 'hello world'

# 使用 re.match
match_result = re.match(pattern, string)
if match_result:
    print("re.match 匹配成功,匹配内容为:", match_result.group())
else:
    print("re.match 匹配失败")

# 使用 re.search
search_result = re.search(pattern, string)
if search_result:
    print("re.search 匹配成功,匹配内容为:", search_result.group())
else:
    print("re.search 匹配失败")

结果分析:在这个例子中,模式 'hello' 位于字符串 'hello world' 的起始位置。因此,re.matchre.search 都能成功匹配,并且都能返回匹配到的 'hello'

示例 2:模式不在字符串起始位置
import re

# 定义字符串和模式
pattern = r'world'
string = 'hello world'

# 使用 re.match
match_result = re.match(pattern, string)
if match_result:
    print("re.match 匹配成功,匹配内容为:", match_result.group())
else:
    print("re.match 匹配失败")

# 使用 re.search
search_result = re.search(pattern, string)
if search_result:
    print("re.search 匹配成功,匹配内容为:", search_result.group())
else:
    print("re.search 匹配失败")

结果分析:模式 'world' 不在字符串 'hello world' 的起始位置,所以 re.match 会匹配失败,返回 None。而 re.search 会在整个字符串中搜索,能够找到 'world' 并返回匹配对象,输出匹配内容 'world'

示例 3:模式部分在起始位置但不完全匹配
import re

# 定义字符串和模式
pattern = r'hello world!'
string = 'hello world'

# 使用 re.match
match_result = re.match(pattern, string)
if match_result:
    print("re.match 匹配成功,匹配内容为:", match_result.group())
else:
    print("re.match 匹配失败")

# 使用 re.search
search_result = re.search(pattern, string)
if search_result:
    print("re.search 匹配成功,匹配内容为:", search_result.group())
else:
    print("re.search 匹配失败")

结果分析:模式 'hello world!' 虽然前部分 'hello world' 与字符串起始部分相同,但整体模式不完全匹配,所以 re.match 会失败。re.search 同样在整个字符串中找不到完全匹配的内容,也会匹配失败。

性能考虑
  • re.match:由于它只从字符串起始位置开始匹配,不需要对整个字符串进行遍历,在某些情况下性能可能会更好,特别是当你明确知道要匹配的内容应该在字符串开头时。
  • re.search:需要遍历整个字符串来查找匹配位置,所以在处理较长字符串时,性能可能会相对较低。但它的灵活性更高,适用于不确定匹配内容位置的情况。

六、正则表达式 re 模块的常用例子

1. 匹配以特定字符开头的字符串

import re

text = "apple banana cherry"
pattern = r'^apple'
result = re.search(pattern, text)
if result:
    print("匹配成功:", result.group())
else:
    print("匹配失败")

2. 匹配以特定字符结尾的字符串

import re

text = "apple banana cherry"
pattern = r'cherry$'
result = re.search(pattern, text)
if result:
    print("匹配成功:", result.group())
else:
    print("匹配失败")

3. 匹配包含特定单词的字符串

import re

text = "The quick brown fox jumps over the lazy dog"
pattern = r'fox'
result = re.search(pattern, text)
if result:
    print("匹配成功:", result.group())
else:
    print("匹配失败")

4. 匹配连续数字

import re

text = "abc123def"
pattern = r'\d+'
result = re.findall(pattern, text)
print("匹配结果:", result)

5. 匹配字母和数字的组合

import re

text = "abc123def"
pattern = r'[a-zA-Z0-9]+'
result = re.findall(pattern, text)
print("匹配结果:", result)

6. 匹配邮箱地址

import re

text = "example@example.com"
pattern = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
result = re.fullmatch(pattern, text)
if result:
    print("匹配成功:", result.group())
else:
    print("匹配失败")

7. 匹配手机号码

import re

text = "13800138000"
pattern = r'^1[3-9]\d{9}$'
result = re.fullmatch(pattern, text)
if result:
    print("匹配成功:", result.group())
else:
    print("匹配失败")

8. 匹配日期格式(YYYY-MM-DD)

import re

text = "2025-03-11"
pattern = r'^\d{4}-\d{2}-\d{2}$'
result = re.fullmatch(pattern, text)
if result:
    print("匹配成功:", result.group())
else:
    print("匹配失败")

9. 替换所有数字为指定字符

import re

text = "abc123def456"
pattern = r'\d+'
replacement = 'X'
result = re.sub(pattern, replacement, text)
print("替换结果:", result)

10. 分割字符串

import re

text = "apple,banana,cherry"
pattern = r','
result = re.split(pattern, text)
print("分割结果:", result)

11. 提取 HTML 标签中的内容

import re

html = '<p>Hello, World!</p>'
pattern = r'<p>(.*?)</p>'
result = re.findall(pattern, html)
print("提取结果:", result)

12. 匹配中文

import re

text = "你好,世界!"
pattern = r'[\u4e00-\u9fa5]+'
result = re.findall(pattern, text)
print("匹配结果:", result)

13. 匹配多个单词中的任意一个

import re

text = "cat dog elephant"
pattern = r'cat|dog'
result = re.findall(pattern, text)
print("匹配结果:", result)

14. 匹配重复的字符

import re

text = "aaaaabbbccc"
pattern = r'(.)\1+'
result = re.findall(pattern, text)
print("匹配结果:", result)

15. 匹配不包含特定字符的字符串

import re

text = "abcde"
pattern = r'[^abc]+'
result = re.findall(pattern, text)
print("匹配结果:", result)

16. 匹配单词边界

import re

text = "The quick brown fox jumps"
pattern = r'\bfox\b'
result = re.search(pattern, text)
if result:
    print("匹配成功:", result.group())
else:
    print("匹配失败")

17. 匹配 IP 地址

import re

text = "192.168.1.1"
pattern = r'^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
result = re.fullmatch(pattern, text)
if result:
    print("匹配成功:", result.group())
else:
    print("匹配失败")

18. 匹配 URL

import re

text = "https://www.example.com"
pattern = r'^https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+'
result = re.fullmatch(pattern, text)
if result:
    print("匹配成功:", result.group())
else:
    print("匹配失败")

19. 统计匹配次数

import re

text = "apple apple banana cherry apple"
pattern = r'apple'
matches = re.findall(pattern, text)
count = len(matches)
print("匹配次数:", count)

20. 使用编译后的正则表达式进行匹配

import re

text = "abc123def"
pattern = re.compile(r'\d+')
result = pattern.findall(text)
print("匹配结果:", result)

网站公告

今日签到

点亮在社区的每一天
去签到