Python正则表达式匹配和替换详细指南

时间:2025-09-09 10:00:03来源:互联网

下面小编就为大家分享一篇Python正则表达式匹配和替换详细指南,具有很好的参考价值,希望对大家有所帮助。

正则表达式是处理文本的强大工具,Python通过re模块提供了完整的正则表达式功能。本文将详细介绍Python中的正则匹配和替换操作。

基础语法

导入re模块

import re

基本元字符

  • . - 匹配任意字符(除了换行符)
  • d - 匹配数字
  • w - 匹配字母、数字、下划线
  • s - 匹配空白字符
  • [] - 字符集
  • * - 0次或多次
  • + - 1次或多次
  • ? - 0次或1次
  • {n} - 恰好n次
  • {n,} - 至少n次
  • {n,m} - n到m次

常用匹配方法

1. re.match() - 从字符串开头匹配

text = "Hello World 2024"
result = re.match(r"Hello", text)
if result:
    print("匹配成功:", result.group())  # 输出: Hello

2. re.search() - 搜索整个字符串

text = "The year is 2024"
result = re.search(r"d{4}", text)
if result:
    print("找到数字:", result.group())  # 输出: 2024

3. re.findall() - 查找所有匹配项

text = "苹果10元, 香蕉5元, 橙子8元"
prices = re.findall(r"d+元", text)
print(prices)  # 输出: ['10元', '5元', '8元']

4. re.finditer() - 返回迭代器

text = "联系: 123-4567, 987-6543"
for match in re.finditer(r"d{3}-d{4}", text):
    print(f"找到电话: {match.group()} 位置: {match.span()}")

替换方法详解

re.sub() 基本用法

text = "今天是2023年12月15日"
# 将年份替换为2024
new_text = re.sub(r"2023", "2024", text)
print(new_text)  # 输出: 今天是2024年12月15日

使用分组和引用

text = "张三 李四 王五"
# 交换姓和名的位置
new_text = re.sub(r"(w+) (w+)", r"2 1", text)
print(new_text)  # 输出: 李四 张三 王五

使用函数进行复杂替换

def double_number(match):
    number = int(match.group())
    return str(number * 2)
text = "数字: 5, 10, 15"
new_text = re.sub(r"d+", double_number, text)
print(new_text)  # 输出: 数字: 10, 20, 30

实际应用案例

案例1:格式化电话号码

def format_phone_number(text):
    # 将各种格式的电话号码统一为: (xxx) xxx-xxxx
    pattern = r"(d{3})[-.s]?(d{3})[-.s]?(d{4})"
    replacement = r"(1) 2-3"
    return re.sub(pattern, replacement, text)
phone_text = "联系: 123-456-7890, 123.456.7890, 123 456 7890"
formatted = format_phone_number(phone_text)
print(formatted)
# 输出: 联系: (123) 456-7890, (123) 456-7890, (123) 456-7890

案例2:清理HTML标签

def remove_html_tags(text):
    # 移除HTML标签,保留文本内容
    return re.sub(r"<[^>]+>", "", text)
html_text = "<h1>标题</h1><p>这是一个<strong>段落</strong></p>"
clean_text = remove_html_tags(html_text)
print(clean_text)  # 输出: 标题这是一个段落

案例3:数据脱敏

def mask_sensitive_data(text):
    # 隐藏身份证号中间部分
    text = re.sub(r"(d{4})d{8}(d{4})", r"1********2", text)
    # 隐藏手机号中间部分
    text = re.sub(r"(d{3})d{4}(d{4})", r"1****2", text)
    return text
sensitive_text = "身份证: 510123199001011234, 手机: 13800138000"
masked_text = mask_sensitive_data(sensitive_text)
print(masked_text)
# 输出: 身份证: 5101********1234, 手机: 138****8000

案例4:Salesforce Flow版本更新

import re
def update_flow_version(rows, flow_name, old_version, new_version):
    """
    更新Salesforce Flow的多语言键名版本号
    """
    updated_rows = []
    
    for row in rows:
        if row and len(row) >= 1:
            key = row[0]
            if key and isinstance(key, str):
                patterns = [
                    (f"Flow.Flow.{flow_name}.{old_version}.", 
                     f"Flow.Flow.{flow_name}.{new_version}."),
                    (f"Flow.AutoLaunchedFlow.{flow_name}.{old_version}.", 
                     f"Flow.AutoLaunchedFlow.{flow_name}.{new_version}."),
                ]
                
                new_key = key
                for pattern, replacement in patterns:
                    if re.search(pattern, key):
                        new_key = re.sub(pattern, replacement, key)
                        break
                
                # 更新行的第一个元素
                updated_row = list(row)
                updated_row[0] = new_key
                updated_rows.append(updated_row)
            else:
                updated_rows.append(row)
        else:
            updated_rows.append(row)
    
    return updated_rows
# 使用示例
rows = [
    ["Flow.Flow.CustomerOnboarding.1.title", "客户入驻流程"],
    ["Flow.AutoLaunchedFlow.CustomerOnboarding.1.description", "自动启动流程"],
    ["Other.Key", "其他值"]
]
updated = update_flow_version(rows, "CustomerOnboarding", "1", "2")
for row in updated:
    print(row)
# 输出:
# ['Flow.Flow.CustomerOnboarding.2.title', '客户入驻流程']
# ['Flow.AutoLaunchedFlow.CustomerOnboarding.2.description', '自动启动流程']
# ['Other.Key', '其他值']

案例5:日志文件处理

def parse_log_file(log_content):
    """
    解析日志文件,提取时间戳、级别和消息
    """
    log_pattern = r"(d{4}-d{2}-d{2} d{2}:d{2}:d{2}) [(w+)] (.+)"
    logs = []
    
    for line in log_content.split('n'):
        match = re.match(log_pattern, line)
        if match:
            timestamp, level, message = match.groups()
            logs.append({
                'timestamp': timestamp,
                'level': level,
                'message': message
            })
    
    return logs
# 示例日志内容
log_content = """2024-01-15 10:30:25 [INFO] 用户登录成功
2024-01-15 10:31:10 [ERROR] 数据库连接失败
2024-01-15 10:32:45 [WARNING] 内存使用率过高"""
parsed_logs = parse_log_file(log_content)
for log in parsed_logs:
    print(f"{log['timestamp']} - {log['level']}: {log['message']}")

高级技巧

1. 编译正则表达式(提高性能)

# 对于需要多次使用的模式,先编译
phone_pattern = re.compile(r"(d{3})-(d{3})-(d{4})")
texts = ["123-456-7890", "987-654-3210"]
for text in texts:
    match = phone_pattern.search(text)
    if match:
        print(f"完整匹配: {match.group()}, 分组: {match.groups()}")

2. 使用命名分组

text = "日期: 2024-01-15"
pattern = r"(?P<year>d{4})-(?P<month>d{2})-(?P<day>d{2})"
match = re.search(pattern, text)
if match:
    print(f"年: {match.group('year')}, 月: {match.group('month')}, 日: {match.group('day')}")

3. 非贪婪匹配

text = "<div>内容1</div><div>内容2</div>"
# 贪婪匹配
greedy = re.findall(r"<div>(.*)</div>", text)
print("贪婪匹配:", greedy)  # 输出: ['内容1</div><div>内容2']
# 非贪婪匹配
non_greedy = re.findall(r"<div>(.*?)</div>", text)
print("非贪婪匹配:", non_greedy)  # 输出: ['内容1', '内容2']

4. 前后查找

text = "价格: $100, 折扣: $20"
# 查找$后面的数字
prices = re.findall(r"(?<=$)d+", text)
print("价格:", prices)  # 输出: ['100', '20']

最佳实践

  1. 使用原始字符串r"pattern" 避免转义问题
  2. 编译常用模式:提高性能
  3. 合理使用分组:使代码更清晰
  4. 处理异常情况:确保匹配失败时不会崩溃
  5. 测试正则表达式:使用在线工具验证模式

总结

正则表达式是Python中处理文本的强大工具,re.sub()函数特别适用于字符串替换任务。通过掌握基本语法和高级技巧,你可以高效地处理各种文本处理需求,从简单的字符串替换到复杂的数据提取和格式化。

记住:正则表达式虽然强大,但也要适度使用,对于简单的字符串操作,Python内置的字符串方法可能更合适。

本站部分内容转载自互联网,如果有网站内容侵犯了您的权益,可直接联系我们删除,感谢支持!