Python 正则表达式:权威指南
tags: python, regex, tutorial, programming
Python 正则表达式:权威指南
想象一下,你正面对一个 10,000 行的日志文件,需要在几秒钟内提取出所有的电子邮件地址、IP 地址和时间戳。如果使用手动字符串切片或嵌套循环来完成这项工作,不仅耗时,还很容易在边界情况下出错。但借助 Python 正则表达式,你可以用一行优雅的代码解决这个问题。正则表达式不仅仅是开发者的超级技能,更是模式匹配、文本验证和数据提取的终极工具。让我们一起掌握它。
Python re 模块入门
在编写复杂的正则模式之前,你需要导入正确的工具。Python 通过内置的 re 模块 来处理正则表达式。它轻量、强大,并且在每一个标准 Python 安装中都可用。
import re
Enter fullscreen mode Exit fullscreen mode
开始时的黄金法则:模式字符串始终使用原始字符串。在字符串前加上 r 前缀(例如 r"\d+"),以防止 Python 在正则引擎看到它们之前就将反斜杠解释为转义字符。这样可以避免微妙的错误,例如 \n 变成换行符,而不是字面上的“反斜杠-n”模式。
你每天都会用到的核心正则函数
re 模块提供了几个函数,但以下四个函数是你 90% 时间里会用到的:
re.search()
扫描整个字符串,如果在任何位置找到匹配的模式,则返回一个匹配对象,否则返回 None。它非常适合用于检查某个条件是否存在。
re.match()
仅检查模式是否在字符串的最开头匹配。如果你的文本以额外的空白字符或无关字符开头,即使模式在后面存在,match() 也可能失败。
re.findall()
返回一个所有非重叠匹配项的列表。这是你提取数据的首选方法,例如从文档中提取所有电话号码。
re.sub()
搜索模式的所有实例,并用新字符串替换它们。可用于清理数据或净化输入。
基本模式与特殊字符
正则表达式模式由普通字符(如 a、5 或 !)和定义规则的元字符构成。以下是你今天就需要掌握的要点:
| 元字符 | 含义 |
|---|---|
. |
任意单个字符(换行符除外) |
^ |
字符串的开头 |
$ |
字符串的结尾 |
\d |
任意数字(0–9) |
\w |
任意单词字符(字母、数字或下划线) |
\s |
任意空白字符(空格、制表符、换行符) |
例如,r"\d{3}-\d{4}" 可以匹配像 555-1234 这样的美国电话号码格式。
量词:控制重复
你经常需要匹配字符的“一个或多个”或“零个或多个”。量词用于处理这种情况:
-
*:零个或多个(例如ab*匹配a、ab、abb) -
+:一个或多个(例如ab+匹配ab、abb,但不匹配a) -
?:零个或一个(例如ab?匹配a或ab) -
{n}:正好 n 次(例如\d{4}匹配正好 4 位数字) -
{n,m}:介于 n 和 m 次之间
锚点与边界
锚点允许你基于位置而非内容进行匹配:
-
^pattern:仅当模式位于开头时才匹配。 -
pattern$:仅当模式位于结尾时才匹配。 -
\b:单词边界(用于匹配整个单词,如\bcat\b,以避免匹配“category”)。
一个实用的工作示例
让我们把所有知识整合起来。假设你有一个杂乱的日志字符串,需要提取所有电子邮件地址,将它们替换为 [REDACTED],并统计找到的数量。
import re
log_text = """
User [email protected] logged in from 192.168.1.1.
Error: Invalid email user@@test.com. Contact [email protected].
Another user: [email protected] tried again.
"""
# 1. Define the email pattern
email_pattern = r"[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z]{2,}"
# 2. Find all emails
emails = re.findall(email_pattern, log_text)
print(f"Found {len(emails)} emails: {emails}")
# 3. Replace them
cleaned_log = re.sub(email_pattern, "[REDACTED]", log_text)
print("\nCleaned Log:")
print(cleaned_log)
Enter fullscreen mode Exit fullscreen mode
输出:
Found 3 emails: ['[email protected]', '[email protected]', '[email protected]']
Cleaned Log:
User [REDACTED] logged in from 192.168.1.1.
Error: Invalid email user@@test.com. Contact [REDACTED].
Another user: [REDACTED] tried again.
Enter fullscreen mode Exit fullscreen mode
请注意,user@@test.com 被忽略了,因为它违反了模式(有两个 @ 符号)。这就是精确正则表达式的强大之处:它会自动过滤噪声。
高级技巧:分组与环视
一旦你掌握了基础知识,就可以探索分组 ( ) 来捕获匹配的一部分。例如,r"(\d{4})-(\d{2})-(\d{2})" 可以将日期拆分为年、月、日。
环视(如 (?=...) 正向先行断言)允许你仅在模式后面跟着另一个模式时才匹配,但结果中不包含第二个部分。这些功能对于复杂验证非常强大,但如果过度使用可能会降低性能。
性能提示与最佳实践
正则表达式很快,但如果写得不好,它可能会变慢。以下是如何保持高效的方法:
-
编译模式以便重复使用:
pattern = re.compile(r"\d+"),然后使用pattern.findall(text)。 - 从简单开始:逐步构建你的模式,并用小输入进行测试。
-
不要过度使用正则表达式:如果简单的字符串方法(如
.split()或.replace())能解决问题,就使用它们。正则表达式用于复杂模式,而不是所有字符串任务。 - 彻底测试:使用 regex101.com 等工具来可视化匹配并调试边界情况。
要点总结
- 始终使用原始字符串(
r"pattern")来避免转义问题。 - 掌握四个核心函数:
search()、match()、findall()、sub()。 - 使用量词(
*、+、?、{n})来控制重复。 - 使用
^和$锚定模式以进行基于位置的匹配。 - 重复使用时编译模式以提升性能。
- 部署前用真实数据测试你的模式。
正则表达式是一项通过练习不断成长的技能。今天就从解决一个小问题开始:验证一个电子邮件、提取一个电话号码,或清理 CSV 列。一旦你看到它如何将杂乱的文本转换为结构化数据,你就再也不会回到手动字符串解析了。
准备好升级了吗?找一个杂乱的文本文件,编写一个正则模式来提取你需要的数据,然后在 Dev.to 的评论区分享你的模式。让我们一起建立一个正则表达式巫师社区!
如果你觉得这篇文章有帮助,可以考虑请我喝杯咖啡 ☕ —— 这能让这些文章继续产出!
也可以看看我的 AI 工具合集:AI 次元世界 —— 面向开发者的免费 AI 工具。
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.