五个案例快速熟悉 Python 正则表达式应用

开发
Python 的 re 库提供了全面的正则表达式支持,让你能够在 Python 程序中轻松地处理各种文本任务。本文将通过五个案例,带大家逐步了解 re 库的常用功能和技巧。

正则表达式 (Regular Expression, 简称 regex 或 regexp) 是一种强大的文本处理工具,它使用预定义的特殊字符和模式来匹配、查找、替换和分割字符串。Python 的 re 库提供了全面的正则表达式支持,让你能够在 Python 程序中轻松地处理各种文本任务。

本文将通过五个案例,带大家逐步了解 re 库的常用功能和技巧。

案例 1: 基础匹配 - 查找邮箱地址

假设你有一段文本信息,其中包含一些邮箱地址,你想从中提取出所有的邮箱地址。

正则表达式: \w+@\w+\.\w+

  • \w: 匹配字母、数字、下划线 (word characters)。
  • +: 匹配前面的字符一次或多次。
  • @:  匹配 @ 符号本身。
  • \.: 匹配 . 符号本身 (需要转义,因为 . 在正则中是特殊字符,匹配任意字符)。
import re

text = "联系我们:support@example.com 或者 sales.department@another-example.net.cn"
pattern = r'\w+@\w+\.\w+' # r'' 表示原始字符串,避免反斜杠转义问题
emails = re.findall(pattern, text) # findall 查找所有匹配项,返回列表

print("原始文本:", text)
print("提取到的邮箱地址:", emails)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

  • r'\w+@\w+\.\w+' 定义了正则表达式模式。r 前缀表示原始字符串,这在正则表达式中非常推荐使用,可以避免反斜杠被 Python 字符串转义误解。
  • re.findall(pattern, text) 函数会在 text 字符串中查找所有符合 pattern 模式的子字符串,并将它们以列表的形式返回。

上面的正则表达式是一个非常基础的邮箱地址匹配模式,它能匹配简单的邮箱格式,但对于更复杂的邮箱地址 (例如包含 . 或 - 在用户名部分) 可能无法完全匹配。在实际应用中,你可能需要更完善的正则表达式来处理各种邮箱格式。 例如,\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* 可以匹配更复杂的邮箱地址。

案例 2: 匹配手机号码

场景:你需要验证用户输入的字符串是否为中国大陆的手机号码。

正则表达式 (简化版):^1[3-9]\d{9}$

  • ^:  匹配字符串的开始位置。
  • 1:  匹配数字 1,中国大陆手机号码通常以 1 开头。
  • [3-9]: 匹配数字 3 到 9 中的任意一个,表示手机号码的第二位数字 (常见的号段第二位)。
  • \d{9}: 匹配 9 个数字 (\d 代表数字,{9} 表示重复 9 次)。
  • $:  匹配字符串的结束位置。
import re

phone_numbers = ["13812345678", "15098765432", "18655551111", "12345678901", "010-88888888"]

pattern = r'^1[3-9]\d{9}$'

for number in phone_numbers:
    if re.match(pattern, number): # match 从字符串的开头开始匹配
        print(f"{number} 是一个有效的手机号码")
    else:
        print(f"{number} 不是有效的手机号码")
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

  • ^1[3-9]\d{9}$ 定义了手机号码的模式。^ 和 $ 确保模式从字符串的开头匹配到结尾,避免匹配到字符串中间部分符合模式的情况。
  • re.match(pattern, number) 函数尝试从 number 字符串的开头匹配 pattern。如果匹配成功,返回一个匹配对象;否则返回 None。

这个正则表达式只是一个简化的版本,实际的手机号码规则非常复杂,号段不断更新。更严格的手机号码验证可能需要更复杂的正则表达式,或者使用专门的手机号码验证库。

案例 3: 分组与提取 - 解析日期格式

你有一系列不同格式的日期字符串,例如 "2023-10-26"、"2023/10/26"、"2023年10月26日",你想统一提取出年、月、日。

正则表达式 (支持多种分隔符): (\d{4})[-/年](\d{1,2})[-/月](\d{1,2})日?

  • (\d{4}):  用括号 () 分组,匹配 4 位数字表示年份。
  • [-/年]: 匹配 -、/ 或 年 字作为分隔符。
  • (\d{1,2}):  分组,匹配 1 到 2 位数字表示月份。
  • [-/月]: 匹配 -、/ 或 月 字作为分隔符。
  • (\d{1,2}):  分组,匹配 1 到 2 位数字表示日期。
  • 日?: 匹配 "日" 字,? 表示 0 次或 1 次,即 "日" 字可选。
import re

dates = ["2023-10-26", "2023/10/26", "2023年10月26日", "2024-1-5", "invalid date"]

pattern = r'(\d{4})[-/年](\d{1,2})[-/月](\d{1,2})日?'

for date_str in dates:
    match = re.search(pattern, date_str) # search 在字符串中搜索第一个匹配项
    if match:
        year = match.group(1) # 获取第一个分组的内容 (年份)
        month = match.group(2) # 获取第二个分组的内容 (月份)
        day = match.group(3)   # 获取第三个分组的内容 (日期)
        print(f"日期字符串: {date_str},  提取结果: 年={year}, 月={month}, 日={day}")
    else:
        print(f"日期字符串: {date_str},  无法解析")
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

  • (\d{4})[-/年](\d{1,2})[-/月](\d{1,2})日? 使用括号 () 创建了三个分组,分别对应年、月、日。
  • re.search(pattern, date_str) 在 date_str 中搜索第一个匹配项。
  • match.group(n) 方法可以获取第 n 个分组匹配到的内容 (从 1 开始计数)。

案例 4: 替换操作 - 统一文本格式

你需要将文本中的所有 "Mr.", "Ms.", "Miss." 等称谓统一替换为 "先生/女士"。

正则表达式 (匹配多种称谓): (Mr\.|Ms\.|Miss\.)

  • (Mr\.|Ms\.|Miss\.):  使用 | (或) 匹配 "Mr.", "Ms.", 或 "Miss."。 注意 . 需要转义 \.。  整个部分用括号分组。
import re

text = "Hello Mr. Smith, how are you? And Ms. Jane, are you doing well?  Also, Miss. Lee is joining us."

pattern = r'(Mr\.|Ms\.|Miss\.)'
replacement = '先生/女士'
new_text = re.sub(pattern, replacement, text) # sub 执行替换操作

print("原始文本:", text)
print("替换后的文本:", new_text)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

  • r'(Mr\.|Ms\.|Miss\.)' 定义了要匹配的称谓模式。
  • re.sub(pattern, replacement, text) 函数会在 text 中查找所有匹配 pattern 的子字符串,并用 replacement 字符串替换它们。

案例 5: 分割字符串 - 按多种分隔符分割

你需要将一段文本按照句号、逗号、问号、感叹号等多种标点符号分割成句子。

正则表达式 (匹配多种标点符号): [.,?!]

  • [.,?!]:  字符集 [] 匹配方括号中列出的任意一个字符,这里匹配句号 .、逗号 ,、问号 ?、感叹号 !。
import re

text = "This is the first sentence. And this is the second, with a comma! Is this the third? Yes it is."

pattern = r'[.,?!]'
sentences = re.split(pattern, text) # split 根据模式分割字符串,返回列表

print("原始文本:", text)
print("分割后的句子列表:", sentences)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

  • r'[.,?!]' 定义了分隔符模式,匹配任何句号、逗号、问号或感叹号。
  • re.split(pattern, text) 函数会根据 pattern 将 text 字符串分割成多个子字符串,并将它们以列表形式返回。 分割符本身不会包含在返回的子字符串中。

总结

这5个案例展示了 re 库在 Python 中处理正则表达式的一些基本和常用功能:

  • re.findall():  查找所有匹配项。
  • re.match():  从字符串开头匹配。
  • re.search():  在字符串中搜索第一个匹配项。
  • re.sub():  替换匹配项。
  • re.split():  根据模式分割字符串。

同时,我们也接触了一些常用的正则表达式语法元素:

  • 字符类: \w, \d, \s, . 等
  • 量词: +, *, ?, {n}, {n,m}
  • 锚点: ^, $
  • 分组: ()
  • 字符集: []
  • 或: |

要深入掌握正则表达式,还需要不断学习和实践。 你可以查阅 Python re 库的官方文档,以及在线正则表达式教程和工具,例如 https://regex101.com/ (一个非常棒的在线正则表达式测试工具)。

责任编辑:赵宁宁 来源: Python数智工坊
相关推荐

2024-09-14 09:18:14

Python正则表达式

2020-03-30 11:25:16

Linux 开源操作系统

2017-08-10 13:13:44

Linux正则表达式

2021-01-27 11:34:19

Python正则表达式字符串

2024-12-16 07:33:45

C#正则表达式

2011-07-11 12:33:30

JAVA

2010-03-03 13:09:10

Linux正则表达式

2010-03-25 18:25:36

Python正则表达式

2018-09-27 15:25:08

正则表达式前端

2020-09-04 09:16:04

Python正则表达式虚拟机

2010-03-01 15:51:59

Python则表达式

2010-03-11 08:55:45

python正则表达式

2019-12-10 10:40:57

Python正则表达式编程语言

2016-09-12 09:57:08

grep命令表达式Linux

2010-03-03 13:22:08

Python正则表达式

2009-09-16 18:19:34

正则表达式组

2019-07-17 15:45:47

正则表达式字符串前端

2017-05-12 10:47:45

Linux正则表达式程序基础

2011-06-02 12:34:16

正则表达式

2009-02-18 09:48:20

正则表达式Java教程
点赞
收藏

51CTO技术栈公众号