如何在 Python 中使用正则表达式捕获组

PythonPythonBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

正则表达式捕获组是 Python 中用于提取和操作文本数据的强大工具。本教程将引导开发者掌握使用捕获组的基本技巧,深入了解这些高级模式匹配机制如何简化复杂的字符串解析和数据提取任务。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/AdvancedTopicsGroup(["Advanced Topics"]) python(("Python")) -.-> python/BasicConceptsGroup(["Basic Concepts"]) python(("Python")) -.-> python/ControlFlowGroup(["Control Flow"]) python(("Python")) -.-> python/FunctionsGroup(["Functions"]) python/BasicConceptsGroup -.-> python/strings("Strings") python/ControlFlowGroup -.-> python/list_comprehensions("List Comprehensions") python/FunctionsGroup -.-> python/function_definition("Function Definition") python/FunctionsGroup -.-> python/lambda_functions("Lambda Functions") python/AdvancedTopicsGroup -.-> python/regular_expressions("Regular Expressions") subgraph Lab Skills python/strings -.-> lab-420906{{"如何在 Python 中使用正则表达式捕获组"}} python/list_comprehensions -.-> lab-420906{{"如何在 Python 中使用正则表达式捕获组"}} python/function_definition -.-> lab-420906{{"如何在 Python 中使用正则表达式捕获组"}} python/lambda_functions -.-> lab-420906{{"如何在 Python 中使用正则表达式捕获组"}} python/regular_expressions -.-> lab-420906{{"如何在 Python 中使用正则表达式捕获组"}} end

正则表达式捕获组基础

什么是捕获组?

捕获组是正则表达式中的一项强大功能,它允许你提取和分组匹配模式的特定部分。在 Python 中,它们是通过在正则表达式模式中使用括号 () 来定义的。

基本语法和用法

简单捕获组示例

import re

text = "Contact email: [email protected]"
pattern = r"(\w+)\.(\w+)@(\w+)\.(\w+)"

match = re.search(pattern, text)
if match:
    username = match.group(1)  ## john
    lastname = match.group(2)  ## doe
    domain = match.group(3)    ## example
    tld = match.group(4)       ## com

    print(f"Username: {username}")
    print(f"Lastname: {lastname}")
    print(f"Domain: {domain}")
    print(f"TLD: {tld}")

捕获组方法

方法 描述 示例
group(0) 返回整个匹配的字符串 完整匹配
group(1) 返回第一个捕获组 第一个括号内的内容
groups() 返回所有捕获组的元组 所有捕获组

捕获组流程

graph TD A[Regex Pattern] --> B{Match Found?} B -->|Yes| C[Extract Capture Groups] B -->|No| D[No Match] C --> E[Process Captured Data]

命名捕获组

Python 还支持命名捕获组,以使代码更具可读性:

import re

text = "Product: Laptop, Price: $999.99"
pattern = r"Product: (?P<product>\w+), Price: \$(?P<price>\d+\.\d+)"

match = re.search(pattern, text)
if match:
    product = match.group('product')
    price = match.group('price')
    print(f"Product: {product}, Price: ${price}")

要点总结

  • 捕获组在正则表达式模式中使用括号 ()
  • 它们允许提取匹配字符串的特定部分
  • 可以通过索引或名称访问
  • 对于解析和提取结构化数据很有用

LabEx 建议通过练习这些概念来掌握 Python 中的正则表达式捕获组。

捕获组的实际应用

数据提取场景

解析日志文件

import re

log_entry = '2023-06-15 14:30:45 [ERROR] Database connection failed'
pattern = r'(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2}) \[(\w+)\] (.+)'

match = re.match(pattern, log_entry)
if match:
    date = match.group(1)
    time = match.group(2)
    log_level = match.group(3)
    message = match.group(4)

    print(f"Date: {date}")
    print(f"Time: {time}")
    print(f"Level: {log_level}")
    print(f"Message: {message}")

URL解析

import re

def parse_url(url):
    pattern = r'(https?://)?([^/]+)(/.*)?'
    match = re.match(pattern, url)

    if match:
        protocol = match.group(1) or 'http://'
        domain = match.group(2)
        path = match.group(3) or '/'

        return {
            'protocol': protocol,
            'domain': domain,
            'path': path
        }

## Example usage
url = 'https://www.example.com/path/to/page'
parsed_url = parse_url(url)
print(parsed_url)

电子邮件验证与提取

import re

def validate_email(email):
    pattern = r'^([a-zA-Z0-9._-]+)@([a-zA-Z0-9.-]+)\.([a-zA-Z]{2,4})$'
    match = re.match(pattern, email)

    if match:
        username = match.group(1)
        domain = match.group(2)
        tld = match.group(3)

        return {
            'valid': True,
            'username': username,
            'domain': domain,
            'tld': tld
        }
    return {'valid': False}

## Example usage
email = '[email protected]'
result = validate_email(email)
print(result)

捕获组工作流程

graph TD A[Input String] --> B[Regex Pattern] B --> C{Match Found?} C -->|Yes| D[Extract Capture Groups] D --> E[Process Extracted Data] C -->|No| F[Handle No Match]

常见用例

场景 正则表达式模式 用例
电话号码 (\d{3})-(\d{3})-(\d{4}) 解析电话号码
日期格式 (\d{4})-(\d{2})-(\d{2}) 提取日期组件
IP 地址 (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}) 网络地址解析

高级替换技巧

import re

def mask_sensitive_data(text):
    pattern = r'(\d{4})-(\d{4})-(\d{4})-(\d{4})'
    return re.sub(pattern, r'\1-****-****-\4', text)

credit_card = '1234-5678-9012-3456'
masked_card = mask_sensitive_data(credit_card)
print(masked_card)

要点总结

  • 捕获组在数据提取方面用途广泛
  • 可用于解析、验证和转换
  • 提供了一种结构化的方式来提取复杂模式
  • LabEx 建议结合实际场景进行练习

复杂正则表达式模式

嵌套捕获组

import re

def parse_complex_data(text):
    pattern = r'((\w+)\s(\w+))\s\[(\d+)\]'
    match = re.match(pattern, text)

    if match:
        full_name = match.group(1)
        first_name = match.group(2)
        last_name = match.group(3)
        id_number = match.group(4)

        return {
            'full_name': full_name,
            'first_name': first_name,
            'last_name': last_name,
            'id': id_number
        }

text = 'John Doe [12345]'
result = parse_complex_data(text)
print(result)

非捕获组

import re

def extract_domain_info(url):
    ## (?:) 创建一个非捕获组
    pattern = r'https?://(?:www\.)?([^/]+)'
    match = re.match(pattern, url)

    if match:
        domain = match.group(1)
        return domain

url = 'https://www.example.com/path'
domain = extract_domain_info(url)
print(domain)

前瞻和后瞻

import re

def validate_password(password):
    ## 正向前瞻用于复杂的密码规则
    pattern = r'^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[!@#$%^&*]).{8,}$'
    return re.match(pattern, password) is not None

passwords = [
    'Weak1',
    'StrongPass123!',
    'NoSpecialChar123'
]

for pwd in passwords:
    print(f"{pwd}: {validate_password(pwd)}")

正则表达式模式复杂度流程

graph TD A[Regex Pattern] --> B{Complexity Level} B -->|Simple| C[Basic Matching] B -->|Intermediate| D[Capture Groups] B -->|Advanced| E[Lookaheads/Lookbehinds] E --> F[Complex Validation]

高级正则表达式技术

技术 符号 描述 示例
非捕获组 (?:) 不捕获的组 (?:www\.)?
正向前瞻 (?=) 后跟时匹配 (?=.*\d)
负向前瞻 (?!) 不跟随时匹配 (?!.*secret)
后瞻 (?<=) 前面是时匹配 (?<=\$)\d+

递归解析

import re

def parse_nested_json(text):
    pattern = r'\{([^{}]*(?:\{[^{}]*\}[^{}]*)*)\}'
    matches = re.findall(pattern, text)
    return matches

json_like = '{key1: value1} {nested: {inner: value}}'
result = parse_nested_json(json_like)
print(result)

性能考虑

import re
import timeit

def optimize_regex(pattern):
    ## 编译正则表达式以提高性能
    compiled_pattern = re.compile(pattern)
    return compiled_pattern

## 基准测试正则表达式编译
pattern = r'(\w+)@(\w+)\.(\w+)'
compilation_time = timeit.timeit(
    lambda: re.compile(pattern),
    number=10000
)
print(f"Compilation Time: {compilation_time}")

要点总结

  • 复杂的正则表达式模式需要精心设计
  • 策略性地使用非捕获组和前瞻组
  • 编译正则表达式模式以提高性能
  • LabEx 建议逐步学习高级技术

总结

通过掌握 Python 中的正则表达式捕获组,开发者能够显著提升他们的文本处理能力。本教程探讨了创建、使用和操作捕获组的基础及高级技巧,使程序员能够运用正则表达式编写更高效、精确的字符串操作代码。