Skip to content

Python 正则表达式

正则表达式(Regular Expression, 或简称 regex)是一个强大的工具,它使用一种专门的语法来搜索、匹配和操作字符串中的特定模式。Python 通过内置的 re 模块来支持正则表达式。

什么是正则表达式?

想象一下,你想在一个长文本中查找所有电话号码或电子邮件地址。这些模式很难用简单的字符串方法(如 find()startswith())来描述。正则表达式允许你定义一个“模式”,然后用这个模式去匹配你想要的任何复杂字符串。

re 模块的核心函数

re.search(pattern, string)

扫描整个字符串,查找模式第一次出现的位置,如果找到则返回一个匹配对象(Match Object),否则返回 None

python
import re

text = "The rain in Spain falls mainly in the plain."

# 查找 'ai' 模式
match = re.search(r"ai", text)

if match:
    print("Match found!")
    print(f"Span: {match.span()}")   # 匹配的起止位置: (5, 7)
    print(f"String: {match.string}") # 原始字符串
    print(f"Group: {match.group()}")   # 匹配到的字符串: 'ai'
else:
    print("No match found.")

r"..." 是什么?r 前缀表示这是一个“原始字符串 (raw string)”。在正则表达式中,反斜杠 \ 有特殊含义(如 \d 表示数字)。使用原始字符串可以防止 Python 解释器对反斜杠进行转义,从而简化正则表达式的书写。

re.findall(pattern, string)

查找字符串中所有与模式匹配的非重叠子串,并以列表形式返回。

python
import re

text = "The rain in Spain falls mainly in the plain."

# 查找所有 'ai' 的实例
all_matches = re.findall(r"ai", text)

print(all_matches) # 输出: ['ai', 'ai', 'ai', 'ai']

re.sub(pattern, repl, string)

查找与模式匹配的子串,并用 repl 替换它们。返回替换后的新字符串。

python
import re

text = "My phone number is 123-456-7890."

# 将电话号码替换为 [REDACTED]
redacted_text = re.sub(r"\d{3}-\d{3}-\d{4}", "[REDACTED]", text)

print(redacted_text) # 输出: My phone number is [REDACTED].

常用的元字符 (Metacharacters)

元字符是正则表达式中有特殊含义的字符。

元字符描述示例匹配
.匹配除换行符外的任意单个字符a.bacb, a_b
^匹配字符串的开头^HelloHello World
$匹配字符串的结尾World$Hello World
*匹配前一个字符 0 次或多次ab*cac, abc, abbbc
+匹配前一个字符 1 次或多次ab+cabc, abbbc (不匹配 ac)
?匹配前一个字符 0 次或 1 次ab?cac, abc
{m,n}匹配前一个字符 m 到 n 次a{2,4}aa, aaa, aaaa
[]字符集,匹配方括号中的任意一个字符[aeiou]a, e, i, o, u
\转义特殊字符,或引入特殊序列\.. (字符本身)
\d匹配任意数字 (等同于 [0-9])\d+123, 45
\D匹配任意非数字字符
\s匹配任意空白字符 (空格, tab, 换行)
\S匹配任意非空白字符
\w匹配任意字母、数字、下划线 (等同于 [a-zA-Z0-9_])
\W匹配任意非字母、数字、下划线字符

分组 (Grouping)

使用圆括号 () 可以对模式进行分组。这有两个主要作用:

  1. 将多个字符作为一个整体来应用量词(如 *, +, ?)。
  2. 捕获匹配的内容,以便后续引用。
python
import re

text = "Email: john.doe@example.com, User: jane_doe"

# 模式匹配一个完整的电子邮件地址
# (\w+\.\w+) 捕获用户名部分
# (\w+\.\w+) 捕获域名部分
match = re.search(r"(\w+\.\w+)@(\w+\.\w+)", text)

if match:
    print(f"Full match: {match.group(0)}") # group(0) 或 group() 是整个匹配
    print(f"Username: {match.group(1)}")   # group(1) 是第一个括号捕获的内容
    print(f"Domain: {match.group(2)}")     # group(2) 是第二个括号捕获的内容

正则表达式是一个非常广阔和强大的领域,掌握它需要不断的练习。建议使用在线工具(如 regex101.com)来测试和学习模式。

本站内容仅供学习和研究使用。