机器学习初学者 22小时前
【Python】100个Python正则表达式技巧,让你从入门到精通
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文系统梳理了 Python 正则表达式的常用特性、基本模式、量词、锚点、字符转义、分组捕获等核心概念,并深入讲解了前瞻后顾、命名组、详细模式等高级用法。文章通过大量代码示例,展示了如何利用 Python 的 `re` 模块进行字符串匹配、查找、替换等操作,并提供了验证电子邮件、电话号码、URL、密码强度等实际应用场景的正则表达式模式。同时,文章还强调了使用原始字符串、编译模式、转义用户输入等提高效率和安全性的技巧,旨在帮助用户全面掌握 Python 正则表达式,高效处理文本数据。

📚 **正则表达式基础与高级特性**:文章介绍了正则表达式作为一种强大的文本模式匹配工具,涵盖了字面字符、字符类、通配符、量词、锚点、字符转义、分组与捕获等基本概念,并进一步阐述了前瞻后顾、非捕获组、命名组、详细模式等高级特性,为理解和使用正则表达式奠定了坚实基础。

💻 **Python `re` 模块的核心用法**:文中详细演示了 Python `re` 模块的 `match`、`search`、`findall`、`sub` 等函数的使用,通过具体代码示例展示了如何编译模式以提高性能,如何进行区分大小写的匹配,以及如何利用捕获组进行替换操作,帮助读者掌握在 Python 中应用正则表达式的实际方法。

🛡️ **实际应用场景与验证模式**:文章提供了多种常见场景下的正则表达式应用,包括但不限于验证电子邮件地址、电话号码、邮政编码、URL、文件路径和密码强度。这些示例不仅展示了正则表达式的灵活性,也为用户在实际开发中处理数据验证提供了直接可用的参考。

💡 **安全高效的正则表达式实践**:文中强调了使用原始字符串(`r''`)避免转义问题,编译模式以提升重复匹配的效率,以及在使用用户输入构建正则表达式时务必进行转义(`re.escape()`)以防注入攻击。这些实践建议对于编写健壮、安全的正则表达式至关重要。

学研妹 2025-07-25 12:03 浙江

掌握 Python 正则表达式:100个实用技巧与案例。

正则表达式(regex 或 regexp)是 Python 中用于模式匹配与文本处理的强大工具。其语法简洁灵活,能够精准描述字符串中的各类模式,在数据提取、格式验证、文本清洗等场景中发挥着重要作用。

本文系统梳理了 Python 正则表达式的高级特性与一系列使用技巧,帮助读者快速掌握!

一、特性

1.正则表达式简介正则表达式是定义搜索模式的字符序列,是用于字符串匹配和处理的多功能工具。在 Python 中,re 模块提供了对正则表达式的支持。

import re
2.基本模式2.1 字面字符
pattern = re.compile(r'hello')
result = pattern.match('hello world')
print(result.group())  # 输出:'hello'
2.2 字符类
pattern = re.compile(r'[aeiou]')
result = pattern.findall('hello world')
print(result)  # 输出:['e', 'o', 'o']
2.3 通配符 .
pattern = re.compile(r'he..o')
result = pattern.match('hello world')
print(result.group())  # 输出:'hello'
3.量词3.1 *+?
pattern = re.compile(r'ab*c')
result = pattern.match('ac')
print(result.group())  # 输出:'ac'
4.锚点4.1 ^(字符串开头)和 $(字符串结尾)
pattern = re.compile(r'^hello')
result = pattern.match('hello world')
print(result.group())  # 输出:'hello'
5.字符转义
pattern = re.compile(r'\d+')  # 匹配一个或多个数字
result = pattern.match('123')
print(result.group())  # 输出:'123'
6.字符集和范围
pattern = re.compile(r'[a-z]')
result = pattern.findall('Hello World')
print(result)  # 输出:['e', 'l', 'l', 'o', 'o', 'r', 'l', 'd']
7.分组和捕获
pattern = re.compile(r'(\d+)-(\d+)-(\d+)')
result = pattern.match('2023-11-25')
print(result.groups())  # 输出:('2023', '11', '25')
8.高级模式8.1 前瞻和后顾
pattern = re.compile(r'(?<=@)\w+')
result = pattern.findall('user@example.com')
print(result)  # 输出:['example']
8.2 非捕获组
pattern = re.compile(r'(?:\d+)-(\d+)-(\d+)')
result = pattern.match('2023-11-25')
print(result.groups())  # 输出:('11', '25')
9.Python 中正则表达式的使用9.1 match 与 search
pattern = re.compile(r'world')
result = pattern.match('hello world')
print(result)  # None
result = pattern.search('hello world')
print(result.group())  # 输出:'world'
9.2 findall
pattern = re.compile(r'\d+')
result = pattern.findall('There are 25 apples and 30 oranges')
print(result)  # 输出:['25', '30']
10.替换和替换操作
pattern = re.compile(r'\d+')
result = pattern.sub('X''There are 25 apples and 30 oranges')
print(result)  # 输出:'There are X apples and X oranges'
11.不区分大小写
pattern = re.compile(r'hello', re.IGNORECASE)
result = pattern.match('HeLLo World')
print(result.group())  # 输出:'HeLLo'

二、有效使用正则表达式的100个技巧

1.通用技巧

使用原始字符串(如 r'\d+')以避免意外的转义字符。

若需多次使用正则表达式模式,建议编译模式以提升性能。
import re
# 不编译模式(重复编译)
for _ in range(1000):
    result = re.match(r'\d+''123')
# 编译模式(仅编译一次)
pattern = re.compile(r'\d+')
for _ in range(1000):
    result = pattern.match('123')

针对多种情况测试正则表达式,确保其正确性。
import re
# 示例:匹配电子邮件地址
pattern = re.compile(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b')
# 测试用例
test_cases = [
    "user@example.com",             # 有效的电子邮件
    "user@company.co.uk",           # 带国家代码的有效电子邮件
    "name123@sub.domain.org",       # 带子域名的有效电子邮件
    "invalid_email@no_tld",         # 无效的电子邮件(无顶级域名)
    "@missing_username.com",        # 无效的电子邮件(无用户名)
    "user@invalid_domain",          # 无效的电子邮件(域名无效)
    "name@server.c",                # 无效的电子邮件(顶级域名过短)
    "name@server.with_space.com",   # 无效的电子邮件(域名含空格)
    "user@@double_at.com",          # 无效的电子邮件(含两个@)
    "user@excessive_length_domain." + "a" * 255# 无效的电子邮件(域名过长)
]
# 用每个测试用例测试模式
for email in test_cases:
    match = pattern.match(email)
    print(f"{email}{'有效' if match else '无效'}")

2.字符类

利用字符类(如 [a-z])匹配指定范围内的任意字符。

使用否定(字符类中的 ^)匹配不在指定范围内的字符(如 [^0-9] 匹配非数字)。

3.量词

需匹配最小内容时,优先使用非贪婪量词(*?+?)。

使用贪婪量词(*+)时需谨慎,避免意外的长匹配。

4.锚点和边界

使用 ^ 和 $ 分别将模式锚定到行的开头和结尾。

利用单词边界(\b)匹配完整单词。

5.选择和分组

使用选择(|)匹配多个模式(如 cat|dog)。

需对模式的特定部分(而非整个模式)应用量词(*+{})或选择(|)时,分组非常有用。

6.字符转义

熟悉常见的字符转义(\d\w\s),分别用于匹配数字、单词字符和空白字符。

若需匹配特殊字符(如 .),需转义(如 \.)。

7.环视

使用正向前瞻((?=...))匹配后面跟有特定模式的内容。

利用负向前瞻((?!...))匹配后面不跟特定模式的内容。

8.替换

使用捕获组在替换中提取并引用匹配字符串的部分内容。
import re
# 示例:替换日期格式
pattern = re.compile(r'(\d{1,2})/(\d{1,2})/(\d{4})')
# 原始字符串
text = "Meeting on 12/25/2022. Deadline is 3/8/2023."
# 使用捕获组进行替换
result = pattern.sub(r'\3-\1-\2', text)
# 打印结果
print(f"原始:{text}")
print(f"修改后:{result}")

尝试使用反向引用(\1\2)在替换中引用捕获组。

9.常见模式

使用 \d+ 匹配一个或多个数字。

使用 ? 匹配可选字符(如 colou?r 匹配 color 或 colour)。

使用 \s+ 匹配空白字符。

10.不区分大小写

使用 re.IGNORECASE 标志启用不区分大小写的匹配。

11.注释

使用 (?#comment) 在正则表达式中添加注释,提高可读性。

12.验证

使用健壮的正则表达式模式验证电子邮件地址。

import re
def validate_email(email):
    # 电子邮件验证的正则表达式模式
    pattern = re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$')
    return bool(pattern.match(email))
# 测试用例
emails = [
    "user@example.com",          # 有效的电子邮件
    "user.name@company.co.uk",   # 带国家代码的有效电子邮件
    "invalid_email@no_tld",      # 无效的电子邮件(无顶级域名)
    "@missing_username.com",     # 无效的电子邮件(无用户名)
    "user@invalid_domain",       # 无效的电子邮件(域名无效)
    "user@@double_at.com",       # 无效的电子邮件(含两个@)
    "user@excessive_length_domain." + "a" * 255# 无效的电子邮件(域名过长)
]
# 验证每个电子邮件并打印结果
for email in emails:
    result = validate_email(email)
    print(f"{email}{'有效' if result else '无效'}")
^[a-zA-Z0-9._%+-]+:匹配用户名部分中一个或多个允许的字符。

@:匹配 @ 符号。

[a-zA-Z0-9.-]+:匹配域名部分中一个或多个允许的字符。

\.:匹配顶级域名前的点(.)。

[a-zA-Z]{2,}$:匹配两个或多个字母的顶级域名。

为电话号码创建正则表达式模式。

import re
def validate_phone_number(phone_number):
    # 带或不带连字符的美国电话号码的正则表达式模式
    pattern = re.compile(r'^\+?1?\s*[-.]?\s*\(?\d{3}\)?[-.]?\s*\d{3}[-.]?\s*\d{4}$')
    return bool(pattern.match(phone_number))
# 测试用例
phone_numbers = [
    "+1 123-456-7890",     # 带国家代码的有效电话号码
    "123.456.7890",        # 带点的有效电话号码
    "(123) 456-7890",      # 带括号的有效电话号码
    "1234567890",          # 无连字符的有效电话号码
    "987-654-3210",        # 无国家代码的有效电话号码
    "invalid_phone_number"# 无效的电话号码
]
# 验证每个电话号码并打印结果
for phone_number in phone_numbers:
    result = validate_phone_number(phone_number)
    print(f"{phone_number}{'有效' if result else '无效'}")
^:断言字符串的开头。

\+?1?:匹配可选的 + 和可选的 1(国家代码)。

\s*[-.]?\s*:匹配可选的空格和可选的连字符或点。

\(?\d{3}\)?:匹配可选的左括号、三个数字和可选的右括号。

[-.]?\s*\d{3}[-.]?\s*\d{4}$:匹配可选的连字符或点、可选的空格、三个数字、可选的连字符或点、可选的空格,以及结尾的四个数字。

为邮政编码创建正则表达式模式。

import re
def validate_zip_code(zip_code):
    # 美国邮政编码的正则表达式模式(5位或9位)
    pattern = re.compile(r'^\d{5}(?:[-\s]\d{4})?$')
    return bool(pattern.match(zip_code))
# 测试用例
zip_codes = [
    "12345",            # 有效的5位邮政编码
    "98765-4321",       # 带连字符的有效的9位邮政编码
    "56789 1234",       # 带空格的有效的9位邮政编码
    "invalid_zip_code"# 无效的邮政编码
]
# 验证每个邮政编码并打印结果
for zip_code in zip_codes:
    result = validate_zip_code(zip_code)
    print(f"{zip_code}{'有效' if result else '无效'}")
^:断言字符串的开头。

\d{5}:匹配5位数字(5位邮政编码)。

(?:[-\s]\d{4})?:使用非捕获组使最后四位数字可选,允许带可选连字符或空格的9位邮政编码格式。

$:断言字符串的结尾。

13.转义用户输入

将用户输入纳入正则表达式时,务必转义用户输入,以防止注入攻击。

import re
def search_string_in_text(user_input, text):
    # 在正则表达式中使用用户输入前安全转义
    escaped_user_input = re.escape(user_input)
    # 在正则表达式模式中使用转义后的用户输入
    pattern = re.compile(f'\\b{escaped_user_input}\\b', re.IGNORECASE)
    # 在文本中搜索转义后的用户输入
    match = pattern.search(text)
    # 打印结果
    if match:
        print(f"找到:'{user_input}' 在 '{text}' 中")
    else:
        print(f"未找到:'{user_input}' 在 '{text}' 中")
# 用用户输入和文本测试
search_string_in_text(".*""这是一段简单的文本。")
re.escape(user_input)re.escape() 函数转义用户输入中的特殊字符,确保它们被视为字面字符而非正则表达式语法的一部分。

\\b{escaped_user_input}\\b{escaped_user_input} 被纳入正则表达式模式,前后包围 \b 单词边界以匹配确切的单词。

re.IGNORECASEre.IGNORECASE 标志用于执行不区分大小写的搜索。

14.命名组

使用命名组((?P<name>...))提高可读性,并通过名称引用捕获的组。

15.详细模式

启用详细模式(re.VERBOSE 或 re.X),允许模式中包含空格和注释,提高可读性。

16.非捕获组

使用非捕获组 (?:...) 进行分组,而不创建捕获组。

17.Unicode 字符

考虑使用 \p{L} 匹配任何 Unicode 字母。

18.转义点号

若需匹配字面点号,使用 \.

19.验证 URL

创建正则表达式模式验证 URL。

import re
def validate_url(url):
    # 验证 URL 的正则表达式模式
    pattern = re.compile(
        r'^(https?|ftp):\/\/'# 协议(http、https、ftp)
        r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|[0-9]{1,3}\.?|[A-Z0-9-]+\.?)'# 域名
        r'(?:\/[^\s]*)?$'# 路径
        , re.IGNORECASE
    )
    return bool(pattern.match(url))
# 测试用例
urls = [
    "http://www.example.com",
    "https://example.com/path",
    "ftp://ftp.example.net/file.txt",
    "invalid-url",
    "ftp://invalid_domain",
    "https://example_with_underscores.com"
]
# 验证每个 URL 并打印结果
for url in urls:
    result = validate_url(url)
    print(f"{url}{'有效' if result else '无效'}")
^(https?|ftp):\/\/:匹配协议(http、https 或 ftp)。

(?: ... | ... ):域名选项的非捕获组。

(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?:匹配典型域名(example.com),带可选子域名。

|[0-9]{1,3}\.?:或者,匹配 IP 地址(带可选尾点)。

|[A-Z0-9-]+\.?:或者,匹配仅含字母数字的域名(example-with-hyphens.com),带可选尾点。

(?:\/[^\s]*)?$:匹配字符串末尾的路径(例如,/path/to/resource)。

re.IGNORECASEre.IGNORECASE 标志用于执行不区分大小写的匹配。

20.提取信息

使用捕获组从字符串中提取特定信息。

import re
def extract_email_info(email):
    # 带捕获组的正则表达式模式,用于提取电子邮件信息
    pattern = re.compile(r'^([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+)\.([a-zA-Z]{2,})$')
    # 用模式匹配电子邮件
    match = pattern.match(email)
    # 使用捕获组提取信息
    if match:
        username, domain, tld = match.groups()
        print(f"电子邮件:{email}")
        print(f"用户名:{username}")
        print(f"域名:{domain}")
        print(f"顶级域名:{tld}")
    else:
        print(f"无效的电子邮件格式:{email}")
# 测试用例
emails = [
    "user@example.com",
    "john.doe@company.co.uk",
    "invalid_email@no_tld",
    "@missing_username.com",
    "user@invalid_domain",
    "user@@double_at.com",
    "user@excessive_length_domain." + "a" * 255
]
# 从每个电子邮件提取信息并打印结果
for email in emails:
    extract_email_info(email)
    print("-" * 30)
^([a-zA-Z0-9._%+-]+):电子邮件用户名部分的捕获组。

@:匹配 @ 符号。

([a-zA-Z0-9.-]+):电子邮件域名部分的捕获组。

\.:匹配顶级域名前的点(.)。

([a-zA-Z]{2,})$:顶级域名的捕获组。

match.groups():以元组形式检索捕获的组。

21.字符集和范围

使用字符集和范围简洁地匹配多个字符。

import re
def match_date_formats(date_string):
    # 带字符集和范围的正则表达式模式,用于匹配日期格式
    pattern = re.compile(r'^\d{1,2}[/\-]\d{1,2}[/\-]\d{2,4}$')
    # 检查日期字符串是否匹配模式
    if pattern.match(date_string):
        print(f"{date_string} 是有效的日期格式。")
    else:
        print(f"{date_string} 不是有效的日期格式。")
# 测试用例
date_strings = [
    "12/25/2022",
    "3-8-2023",
    "invalid_date",
    "2023-12-31",
    "15/07/2021",
    "22-10-21"
]
# 每个日期字符串与模式匹配并打印结果
for date_str in date_strings:
    match_date_formats(date_str)
^\d{1,2}[/\-]\d{1,2}[/\-]\d{2,4}$:此正则表达式模式使用字符集和范围匹配不同的日期格式。

^\d{1,2}:匹配开头的1或2位数字。

[/\-]:匹配斜杠(/)或连字符(-)。

\d{1,2}:匹配1或2位数字(月份)。

[/\-]:匹配另一个斜杠(/)或连字符(-)。

\d{2,4}$:匹配结尾的2、3或4位数字(年份)。

22.非贪婪字符匹配

组合 .*? 用于非贪婪匹配任何字符。

23.匹配整个单词

使用 \b 匹配整个单词。

24.匹配特殊字符

要匹配字面意义上的 +* 和 ? 等特殊字符,需要转义它们。

25.组上的量词

将量词应用于组以匹配重复模式(例如,(ab)+)。

26.匹配日期

创建正则表达式模式匹配日期格式。

模式1:MM/DD/YYYY 或 MM-DD-YYYY

import re
def match_date_format_1(date_string):
    pattern = re.compile(r'^(0[1-9]|1[0-2])[/\-](0[1-9]|[12][0-9]|3[01])[/\-]\d{4}$')
    if pattern.match(date_string):
        print(f"{date_string} 匹配模式。")
    else:
        print(f"{date_string} 不匹配模式。")
# 测试用例
dates_pattern_1 = ["12/25/2022""03-08-2023""15/07/2021""2023-12-31""invalid_date"]
for date_str in dates_pattern_1:
    match_date_format_1(date_str)
^(0[1-9]|1[0-2])[/\-](0[1-9]|[12][0-9]|3[01])[/\-]\d{4}$
匹配两位数字的月份、两位数字的日期和四位数字的年份,以斜杠(/)或连字符(-)分隔。

模式2:YYYY/MM/DD 或 YYYY-MM-DD

import re
def match_date_format_2(date_string):
    pattern = re.compile(r'^\d{4}[/\-](0[1-9]|1[0-2])[/\-](0[1-9]|[12][0-9]|3[01])$')
    if pattern.match(date_string):
        print(f"{date_string} 匹配模式。")
    else:
        print(f"{date_string} 不匹配模式。")
# 测试用例
dates_pattern_2 = ["2022/12/25""2023-03-08""2021/15/07""2023-12-31""invalid_date"]
for date_str in dates_pattern_2:
    match_date_format_2(date_str)
^\d{4}[/\-](0[1-9]|1[0-2])[/\-](0[1-9]|[12][0-9]|3[01])$
匹配四位数字的年份、两位数字的月份和两位数字的日期,以斜杠(/)或连字符(-)分隔。

模式3:DD Month YYYY

import re
def match_date_format_3(date_string):
    pattern = re.compile(r'^(0[1-9]|[12][0-9]|3[01])\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d{4}$', re.IGNORECASE)
    if pattern.match(date_string):
        print(f"{date_string} 匹配模式。")
    else:
        print(f"{date_string} 不匹配模式。")
# 测试用例
dates_pattern_3 = ["25 Dec 2022""08 March 2023""15/07/2021""31 October 2023""invalid_date"]
for date_str in dates_pattern_3:
    match_date_format_3(date_str)
^(0[1-9]|[12][0-9]|3[01])\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d{4}$
匹配两位数字的日期、三位字母的月份缩写和四位数字的年份,以空格分隔。

27.匹配 HTML 标签

使用正则表达式匹配或提取 HTML 标签中的内容。

import re
def extract_content_from_html(html):
    # 匹配 HTML 标签内内容的正则表达式模式
    pattern = re.compile(r'<[^>]*>([^<]+)<[^>]*>')
    # 在 HTML 中查找所有匹配项
    matches = pattern.findall(html)
    # 打印提取的内容
    for match in matches:
        print(f"提取的内容:{match.strip()}")
# HTML 字符串
html_content = """
<html>
  <body>
    <h1>Title</h1>
    <p>This is a <strong>sample</strong> paragraph.</p>
    <div class="content">Some <em>italicized</em> text.</div>
  </body>
</html>
"""
# 从 HTML 标签提取内容
extract_content_from_html(html_content)
<[^>]*>:匹配开头 HTML 标签(<),后跟零个或多个非 > 字符([^>]*),以及结尾 HTML 标签(>)。

([^<]+):用于匹配和提取 HTML 标签内内容的捕获组。它匹配一个或多个非 < 字符。

<[^>]*>:匹配结尾 HTML 标签。

findall:在 HTML 字符串中查找模式的所有出现。

28.密码验证

设计正则表达式模式验证密码强度。

import re
def validate_password_strength(password):
    # 验证强密码的正则表达式模式
    pattern = re.compile(
        r'^(?=.*[a-z])'     # 至少一个小写字母
        r'(?=.*[A-Z])'      # 至少一个大写字母
        r'(?=.*\d)'         # 至少一个数字
        r'(?=.*[@$!%*?&])'# 至少一个特殊字符
        r'(?=^[^\s]{8,}$)'# 最小长度为8个字符,不允许空格
    )
    if pattern.match(password):
        print(f"{password} 是强密码。")
    else:
        print(f"{password} 不符合密码强度标准。")
# 测试用例
passwords = [
    "StrongPass123!",
    "WeakPassword",
    "NoSpecialCharacter1",
    "Short!23",
    "NoUpperLowerCase@1"
]
# 验证每个密码并打印结果
for password in passwords:
    validate_password_strength(password)
(?=.*[a-z]):至少一个小写字母。

(?=.*[A-Z]):至少一个大写字母。

(?=.*\d):至少一个数字。

(?=.*[@$!%*?&]):至少一个特殊字符(可自定义这个集合)。

(?=^[^\s]{8,}$):最小长度为8个字符,且不允许空格。

29.替换空白字符

用单个空格(\s+)替换连续的空白字符。

30.提取数字

使用 \d+ 从字符串中提取数字。

31.提取 URL

创建正则表达式模式从文本中提取 URL。

模式1:基本 URL 提取

import re
def extract_urls(text):
    # 提取 URL 的正则表达式模式
    pattern = re.compile(r'https?://\S+|www\.\S+')
    # 在文本中查找所有匹配项
    matches = pattern.findall(text)
    # 打印提取的 URL
    for match in matches:
        print(f"提取的 URL:{match}")
# 测试用例
text_with_urls = """
Check out this website: https://www.example.com.
For more information, visit http://www.another-example.org.
"""
# 从文本中提取 URL
extract_urls(text_with_urls)
https?:匹配 "http" 或 "https"。

://:匹配 "://"。

\S+:匹配一个或多个非空白字符(域名)。

|:或运算符。

www\.\S+:匹配 "www." 后跟一个或多个非空白字符。

模式2:扩展 URL 提取

import re
def extract_urls_extended(text):
    # 提取带可选 www 和查询参数的 URL 的正则表达式模式
    pattern = re.compile(r'https?://(?:www\.)?\S+(?:\?\S+)?')
    # 在文本中查找所有匹配项
    matches = pattern.findall(text)
    # 打印提取的 URL
    for match in matches:
        print(f"提取的 URL:{match}")
# 测试用例
text_with_urls_extended = """
Check out this website: https://www.example.com/path/page?query=123.
For more information, visit http://another-example.org.
"""
# 从文本中提取 URL
extract_urls_extended(text_with_urls_extended)
(?:www\.)?:可选 "www." 的非捕获组。

(?:\?\S+)?):可选查询参数(以 "?" 开头)的非捕获组。

32.匹配 HTML 实体

使用正则表达式匹配或替换 HTML 实体。

import re
from html import unescape
def replace_html_entities(text):
    # 匹配 HTML 实体的正则表达式模式
    pattern = re.compile(r'&[a-zA-Z]+;')
    # 在文本中查找所有匹配项
    matches = pattern.findall(text)
    # 将每个 HTML 实体替换为其解码后的等效字符
    for match in matches:
        decoded_entity = unescape(match)
        text = text.replace(match, decoded_entity)
    return text
# 测试用例
html_text = "This is an example with <b>HTML</b> entities."
# 替换文本中的 HTML 实体
result_text = replace_html_entities(html_text)
# 打印结果
print("原始文本:", html_text)
print("替换后:", result_text)
正则表达式模式 &[a-zA-Z]+; 用于匹配常见的 HTML 实体。然后使用 html 模块中的 unescape 函数将每个 HTML 实体替换为其解码后的等效字符。

33.匹配文件路径

设计正则表达式模式匹配文件路径。

模式1:Unix/Linux 文件路径

import re
def match_unix_file_path(path):
    # 匹配 Unix/Linux 文件路径的正则表达式模式
    pattern = re.compile(r'^\/(?:[^\/]+\/)*[^\/]+$')
    if pattern.match(path):
        print(f"{path} 是有效的 Unix/Linux 文件路径。")
    else:
        print(f"{path} 不是有效的 Unix/Linux 文件路径。")
# 测试用例
unix_paths = [
    "/home/user/documents/file.txt",
    "/var/www/html/index.html",
    "relative/path/to/file",
    "invalid\\path\\file.txt"
]
for path in unix_paths:
    match_unix_file_path(path)
^:断言字符串的开头。

\/:匹配根目录("/")。

(?:[^\/]+\/)*:非捕获组,匹配零个或多个非斜杠字符后跟斜杠的序列。

[^\/]+$:匹配字符串末尾一个或多个非斜杠字符。

模式2:Windows 文件路径

import re
def match_windows_file_path(path):
    # 匹配 Windows 文件路径的正则表达式模式
    pattern = re.compile(r'^[a-zA-Z]:\\(?:[^\\]+\\)*[^\\]+$')
    if pattern.match(path):
        print(f"{path} 是有效的 Windows 文件路径。")
    else:
        print(f"{path} 不是有效的 Windows 文件路径。")
# 测试用例
windows_paths = [
    "C:\\Users\\User\\Documents\\file.txt",
    "D:/Projects/project1/code.py",
    "\\absolute\\path\\file.txt",
    "/unix/style/path/file"
]
for path in windows_paths:
    match_windows_file_path(path)
^:断言字符串的开头。

[a-zA-Z]:\\:匹配驱动器号(例如,"C:")后跟反斜杠。

(?:[^\\]+\\)*:非捕获组,匹配零个或多个非反斜杠字符后跟反斜杠的序列。

[^\\]+$:匹配字符串末尾一个或多个非反斜杠字符。

34.提取电子邮件地址

创建正则表达式模式从文本中提取电子邮件地址。

模式1:基本电子邮件地址提取

import re
def extract_email_addresses(text):
    # 基本电子邮件地址提取的正则表达式模式
    pattern = re.compile(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b')
    # 在文本中查找所有匹配项
    matches = pattern.findall(text)
    # 打印提取的电子邮件地址
    for match in matches:
        print(f"提取的电子邮件:{match}")
# 测试用例
text_with_emails = """
Contact us at support@example.com for assistance.
Send your inquiries to info@company.org or sales@business.com.
Invalid emails: user@invalid, @missing_username.com, email@in@valid.com
"""
# 从文本中提取电子邮件地址
extract_email_addresses(text_with_emails)
\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b

\b:单词边界,确保匹配整个电子邮件地址。

[A-Za-z0-9._%+-]+:匹配电子邮件的用户名部分。

@:匹配 @ 符号。

[A-Za-z0-9.-]+:匹配域名。

\.:匹配顶级域名前的点。

[A-Z|a-z]{2,}:匹配至少2个字符的顶级域名(TLD)。

模式2:扩展电子邮件地址提取

import re
def extract_email_addresses_extended(text):
    # 扩展电子邮件地址提取的正则表达式模式
    pattern = re.compile(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}(?:\.[A-Z|a-z]{2,})?\b')
    # 在文本中查找所有匹配项
    matches = pattern.findall(text)
    # 打印提取的电子邮件地址
    for match in matches:
        print(f"提取的电子邮件:{match}")
# 测试用例
text_with_emails_extended = """
Contact us at support@example.com for assistance.
Send your inquiries to info@company.org or sales@business.co.uk.
Invalid emails: user@invalid, @missing_username.com, email@in@valid.com
"""
# 从文本中提取电子邮件地址
extract_email_addresses_extended(text_with_emails_extended)
...(?:\.[A-Z|a-z]{2,})?\b

(?: ... )?:可选附加子域名的非捕获组。

\.:匹配附加子域名前的点。

[A-Z|a-z]{2,}:匹配至少2个字符的附加子域名。

35.匹配 IPv4 地址

设计正则表达式模式匹配 IPv4 地址。

模式1:基本 IPv4 地址匹配

import re
def match_ipv4_addresses(text):
    # 基本 IPv4 地址匹配的正则表达式模式
    pattern = re.compile(r'\b(?:\d{1,3}\.){3}\d{1,3}\b')
    # 在文本中查找所有匹配项
    matches = pattern.findall(text)
    # 打印匹配的 IPv4 地址
    for match in matches:
        print(f"匹配的 IPv4 地址:{match}")
# 测试用例
text_with_ipv4 = """
Server 1: 192.168.1.1
Server 2: 10.0.0.255
Invalid IP: 256.256.256.256
"""
# 在文本中匹配 IPv4 地址
match_ipv4_addresses(text_with_ipv4)
\b(?:\d{1,3}\.){3}\d{1,3}\b

\b:单词边界,确保匹配整个 IPv4 地址。

(?:\d{1,3}\.){3}:非捕获组,匹配三次 "1-3 位数字后跟点"。

\d{1,3}:匹配最后一个八位字节(1-3 位数字)。

模式2:扩展 IPv4 地址匹配

import re
def match_ipv4_addresses_extended(text):
    # 扩展 IPv4 地址匹配的正则表达式模式
    pattern = re.compile(r'\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
                       r'(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}\b')
    # 在文本中查找所有匹配项
    matches = pattern.findall(text)
    # 打印匹配的 IPv4 地址
    for match in matches:
        print(f"匹配的 IPv4 地址:{match}")
# 测试用例
text_with_ipv4_extended = """
Server 1: 192.168.1.1
Server 2: 10.0.0.255
Invalid IP: 256.256.256.256
"""
# 在文本中匹配 IPv4 地址
match_ipv4_addresses_extended(text_with_ipv4_extended)
\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)

(?: ... ){3}:非捕获组,匹配三次以下模式。

25[0-5]:匹配 250 到 255 之间的数字。

2[0-4][0-9]:匹配 200 到 249 之间的数字。

[01]?[0-9][0-9]?:匹配 0 到 199 之间的数字。

36.转义符上的量词

将量词直接应用于转义符(例如,\d{3} 匹配三位数字)。

37.匹配信用卡号

创建正则表达式模式匹配或验证信用卡号。

模式1:基本信用卡号验证

import re
def validate_credit_card_number_basic(card_number):
    # 基本信用卡号验证的正则表达式模式
    pattern = re.compile(r'^\d{13,19}$')
    if pattern.match(card_number):
        print(f"{card_number} 可能是有效的信用卡号。")
    else:
        print(f"{card_number} 不是有效的信用卡号。")
# 测试用例
credit_cards_basic = [
    "1234567890123",
    "4567-8901-2345-6789",
    "1234 5678 9012 3456",
    "invalid_card",
]
for card in credit_cards_basic:
    validate_credit_card_number_basic(card)
^\d{13,19}$:匹配长度在13到19个字符之间的数字字符串。

模式2:带卢恩算法的信用卡号验证

import re
def validate_credit_card_number_luhn(card_number):
    # 带卢恩算法的信用卡号验证的正则表达式模式
    pattern = re.compile(r'^\d{13,19}$')
    ifnot pattern.match(card_number):
        print(f"{card_number} 不是有效的信用卡号。")
        return
    # 移除非数字字符
    digits = [int(digit) for digit in card_number if digit.isdigit()]
    # 应用卢恩算法
    total = sum(digits[::-2] + [sum(divmod(d * 210)) for d in digits[-2::-2]])
    if total % 10 == 0:
        print(f"{card_number} 是有效的信用卡号。")
    else:
        print(f"{card_number} 不是有效的信用卡号。")
# 测试用例
credit_cards_luhn = [
    "1234567890123",
    "4567-8901-2345-6789",
    "1234 5678 9012 3456",
    "invalid_card",
]
for card in credit_cards_luhn:
    validate_credit_card_number_luhn(card)
^\d{13,19}$:与基本模式相同,用于初始数字验证。

卢恩算法用于检查信用卡号的有效性。

38.匹配特定单词

使用 \b 匹配较大文本中的特定单词。

39.转义字符

使用 \ 转义特殊字符,如 ^$()[]{}.*+?|\

在非特殊字符前使用 \ 以字面匹配它。

40.Unicode 和单词边界

使用 \b 作为单词边界,\B 作为非单词边界。

对于 Unicode 单词边界,结合 re.UNICODE 标志使用 \b

41.匹配或排除字符

使用 . 匹配除换行符外的任何字符。

使用 [^...] 匹配不在指定集合中的任何字符。

42.量词组合

组合量词以提高灵活性(例如,a{2,4} 匹配 'aa'、'aaa' 或 'aaaa')。

使用 {0,} 或 * 表示零次或多次出现。

43.分组和选择

使用括号进行分组,并对序列应用量词。

import re
# 包含电话号码的示例文本
text = """
Phone Numbers:
- (555) 123-4567
- (123) 456-7890
- (987) 654-3210
"""
# 带分组和量词的正则表达式模式,用于匹配电话号码
pattern = re.compile(r'\(\d{3}\) \d{3}-\d{4}')
# 在文本中查找所有匹配项
matches = pattern.findall(text)
# 打印匹配的电话号码
for match in matches:
    print("匹配的电话号码:", match)
\(:匹配左括号。

\d{3}:匹配恰好三位数字。

\):匹配右括号。

:匹配空格。

\d{3}:匹配恰好三位数字。

-:匹配连字符。

\d{4}:匹配恰好四位数字。

利用 (?:...) 作为非捕获组。

利用选择匹配多个可能的模式(例如,cat|dog|bird)。

44.替换中的捕获组

在替换模式中使用 \1\2 等利用捕获组。

对命名捕获组使用 \g<name>

45.环视

使用正向后顾((?<=...))匹配前面有特定模式的内容。

应用负向后顾((?<!...))匹配前面没有特定模式的内容。

利用正向前瞻((?=...))匹配后面有特定模式的内容。

利用负向前瞻((?!...))匹配后面没有特定模式的内容。

46.命名捕获组

使用命名捕获组提高代码可读性。

使用 match.group('name') 访问命名捕获组。

47.详细模式

启用详细模式(re.VERBOSE 或 re.X),支持多行模式和注释。

将复杂模式拆分为多行,提高可读性。
import re
# 包含电子邮件地址的示例文本
text = """
Email Addresses:
- user@example.com
- john.doe@company.org
- contact@my-website.co.uk
"""
# 带换行符的正则表达式模式,提高可读性
pattern = re.compile(
    r'\b'                    # 单词边界
    r'[a-zA-Z0-9._%+-]+@'    # 用户名部分
    r'[a-zA-Z0-9.-]+\.'      # 域名部分(第一级)
    r'[A-Z|a-z]{2,}'         # 域名部分(顶级)
    r'\b'                    # 单词边界
)
# 在文本中查找所有匹配项
matches = pattern.findall(text)
# 打印匹配的电子邮件地址
for match in matches:
    print("匹配的电子邮件地址:", match)

48.标志和模式

利用标志,如 re.IGNORECASE 进行不区分大小写的匹配。

使用按位 OR 组合多个标志(例如,re.IGNORECASE | re.MULTILINE)。

49.验证和提取电子邮件域名

使用正则表达式模式验证电子邮件域名。

import re
def validate_email_domain(email):
    # 基本电子邮件地址验证的正则表达式模式
    email_pattern = re.compile(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b')
    # 检查电子邮件地址是否匹配模式
    ifnot email_pattern.match(email):
        print(f"{email} 不是有效的电子邮件地址。")
        return
    # 从电子邮件地址提取域名
    domain_pattern = re.compile(r'@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b')
    domain_match = domain_pattern.search(email)
    if domain_match:
        domain = domain_match.group()[1:]
        print(f"{email} 的域名是 {domain}。")
    else:
        print(f"无法从 {email} 提取域名。")
# 测试用例
emails = [
    "user@example.com",
    "john.doe@company.org",
    "invalid-email",
]
for email in emails:
    validate_email_domain(email)
请注意,这种方法有局限性,不能保证域名的有效性。对于更可靠的解决方案,考虑使用专门的电子邮件验证库或服务。使用 DNS 查找验证域名是更可靠的方法,但需要正则表达式之外的额外步骤。

email_pattern 正则表达式与基本电子邮件地址验证中使用的相同。

domain_pattern 正则表达式用于从电子邮件地址提取域名部分。

@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b:匹配 @ 符号后的域名部分。

使用模式中的捕获组提取电子邮件域名。

import re
def extract_email_domain(email):
    # 带捕获组的正则表达式模式,用于提取电子邮件域名
    pattern = re.compile(r'\b[A-Za-z0-9._%+-]+@([A-Za-z0-9.-]+\.[A-Z|a-z]{2,})\b')
    # 用模式匹配电子邮件地址
    match = pattern.search(email)
    if match:
        domain = match.group(1)
        print(f"{email} 的域名是 {domain}。")
    else:
        print(f"无法从 {email} 提取域名。")
# 测试用例
emails = [
    "user@example.com",
    "john.doe@company.org",
    "invalid-email",
]
for email in emails:
    extract_email_domain(email)
\b[A-Za-z0-9._%+-]+@([A-Za-z0-9.-]+\.[A-Z|a-z]{2,})\b

group(1) 方法用于提取第一个(也是唯一一个)捕获组捕获的内容,即电子邮件域名。

\b:单词边界,确保匹配整个电子邮件地址。

[A-Za-z0-9._%+-]+:匹配电子邮件的用户名部分。

@:匹配 @ 符号。

([A-Za-z0-9.-]+\.[A-Z|a-z]{2,}):域名部分的捕获组。

\b:单词边界,确保匹配整个电子邮件地址。

50.匹配平衡括号

创建正则表达式匹配带平衡括号的表达式。

import regex
def is_balanced(expression):
    # 匹配带平衡括号的表达式的正则表达式模式
    pattern = regex.compile(r'''
        \(
            (?: [^()]+ | (?R) )*
        \)
    ''', regex.VERBOSE)
    return bool(pattern.fullmatch(expression))
# 测试用例
expressions = [
    "(a + b) * (c - d)",
    "((x + y) * z)",
    "((a + b) * (c - d)",
    "a + b) * (c - d)",
]
for expr in expressions:
    if is_balanced(expr):
        print(f"表达式 '{expr}' 有平衡的括号。")
    else:
        print(f"表达式 '{expr}' 没有平衡的括号。")
\(:匹配左括号。

(?: [^()]+ | (?R) )*:非捕获组,零次或多次出现以下内容:

[^()]+:除括号外的任何字符序列。

(?R):递归匹配整个模式。

\):匹配右括号。

Python 中的 regex 模块支持递归模式,允许定义引用自身的模式。在这种情况下,模式 (?R) 用于递归匹配整个模式。

51.验证 IP 地址

设计正则表达式模式验证 IPv4 和 IPv6 地址。

import re
def validate_ipv4_address(ipv4):
    # IPv4 地址验证的正则表达式模式
    pattern = re.compile(
        r'^'
        r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.'
        r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.'
        r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.'
        r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
    )
    return bool(pattern.match(ipv4))
# 测试用例
ipv4_addresses = [
    "192.168.1.1",
    "10.0.0.255",
    "256.256.256.256",
    "invalid-ip",
]
for ipv4 in ipv4_addresses:
    if validate_ipv4_address(ipv4):
        print(f"{ipv4} 是有效的 IPv4 地址。")
    else:
        print(f"{ipv4} 不是有效的 IPv4 地址。")
import re
def validate_ipv6_address(ipv6):
    # IPv6 地址验证的正则表达式模式
    pattern = re.compile(
        r'^'
        r'(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$'
    )
    return bool(pattern.match(ipv6))
# 测试用例
ipv6_addresses = [
    "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
    "invalid-ipv6",
]
for ipv6 in ipv6_addresses:
    if validate_ipv6_address(ipv6):
        print(f"{ipv6} 是有效的 IPv6 地址。")
    else:
        print(f"{ipv6} 不是有效的 IPv6 地址。")
IPv4 地址验证:

IPv6 地址验证:

(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}:验证 IPv6 地址块。

::匹配冒号分隔符。

^:断言字符串的开头。

(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?):验证每个八位字节。

\.:匹配点分隔符。

$:断言字符串的结尾。

使用该模式从文本中提取 IP 地址。

import re
def extract_ip_addresses(text):
    # IPv4 地址提取的正则表达式模式
    ipv4_pattern = re.compile(r'\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b')
    # IPv6 地址提取的正则表达式模式
    ipv6_pattern = re.compile(r'\b(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\b')
    # 在文本中查找所有匹配项
    ipv4_matches = ipv4_pattern.findall(text)
    ipv6_matches = ipv6_pattern.findall(text)
    # 打印匹配的 IP 地址
    print("IPv4 地址:")
    for ipv4_match in ipv4_matches:
        print(ipv4_match)
    print("\nIPv6 地址:")
    for ipv6_match in ipv6_matches:
        print(ipv6_match)
# 测试用例
sample_text = """
本文中的 IP 地址:
- IPv4:192.168.1.1、10.0.0.255、256.256.256.256
- IPv6:2001:0db8:85a3:0000:0000:8a2e:0370:7334
"""
extract_ip_addresses(sample_text)

52.匹配 Markdown 链接

创建正则表达式模式匹配和提取 Markdown 文本中的链接。

import re
def extract_markdown_links(markdown_text):
    # 提取行内链接的正则表达式模式
    inline_link_pattern = re.compile(r'\[([^\]]+)\]\(([^)]+)\)')
    # 提取引用式链接的正则表达式模式
    reference_link_pattern = re.compile(r'\[([^\]]+)\]:\s*([^\s]+)')
    # 在文本中查找所有行内链接
    inline_links = inline_link_pattern.findall(markdown_text)
    # 在文本中查找所有引用式链接
    reference_links = reference_link_pattern.findall(markdown_text)
    # 打印提取的链接
    print("行内链接:")
    for title, url in inline_links:
        print(f"标题:{title},URL:{url}")
    print("\n引用式链接:")
    for title, url in reference_links:
        print(f"标题:{title},URL:{url}")
# 测试用例
sample_markdown = """
Here are some links in Markdown:
- [Google](https://www.google.com)
- [OpenAI](https://www.openai.com)
Reference-style links:
[Markdown Guide]: https://www.markdownguide.org
[GitHub]: https://github.com
"""
extract_markdown_links(sample_markdown)
inline_link_pattern 正则表达式捕获方括号([])内的文本作为链接标题,圆括号(())内的文本作为链接 URL。

reference_link_pattern 正则表达式捕获方括号([])内的文本作为链接标题,冒号(:)后的文本(含可选空格)作为链接 URL。

53.匹配带引号的字符串

设计正则表达式模式匹配文本中的带引号字符串。

import re
def extract_quoted_strings(text):
    # 提取单引号字符串的正则表达式模式
    single_quoted_pattern = re.compile(r"'([^']+)'")
    # 提取双引号字符串的正则表达式模式
    double_quoted_pattern = re.compile(r'"([^"]+)"')
    # 在文本中查找所有单引号字符串
    single_quoted_strings = single_quoted_pattern.findall(text)
    # 在文本中查找所有双引号字符串
    double_quoted_strings = double_quoted_pattern.findall(text)
    # 打印提取的带引号字符串
    print("单引号字符串:")
    for single_quoted in single_quoted_strings:
        print(single_quoted)
    print("\n双引号字符串:")
    for double_quoted in double_quoted_strings:
        print(double_quoted)
# 测试用例
sample_text = """
Here are some quoted strings in the text:
- Single-quoted: 'Hello, world!'
- Double-quoted: "This is a quoted string."
Mixed quotes: 'Single and "double" quotes.'
"""
extract_quoted_strings(sample_text)
single_quoted_pattern 正则表达式捕获单引号(')内的文本作为单引号字符串的内容。

double_quoted_pattern 正则表达式捕获双引号(")内的文本作为双引号字符串的内容。

54.提取 HTML 属性

构建模式从文本中提取 HTML 标签属性。

import re
def extract_html_attributes(html_text):
    # 提取 HTML 标签属性的正则表达式模式
    pattern = re.compile(r'<\s*([a-zA-Z0-9_-]+)(?:\s+([a-zA-Z0-9_-]+)\s*=\s*(".*?"|\'.*?\'|[^\s>]+))*\s*/?>')
    # 在文本中查找所有 HTML 标签
    matches = pattern.finditer(html_text)
    # 提取并打印标签名称和属性
    for match in matches:
        tag_name = match.group(1)
        print(f"标签:{tag_name}")
        if match.group(2):
            attributes = match.group(2)
            attribute_pattern = re.compile(r'([a-zA-Z0-9_-]+)\s*=\s*(".*?"|\'.*?\'|[^\s>]+)')
            # 提取并打印单个属性
            for attribute_match in attribute_pattern.finditer(attributes):
                attribute_name = attribute_match.group(1)
                attribute_value = attribute_match.group(2)
                print(f"  属性:{attribute_name},值:{attribute_value}")
# 测试用例
sample_html = """
<div class="container" id='main-container' data-value=42>
    <p style="color: blue;">This is a paragraph</p>
    <a href="https://example.com" target="_blank">Visit Example</a>
</div>
"""
extract_html_attributes(sample_html)
pattern 正则表达式捕获标签名称及其属性。

attribute_pattern 正则表达式捕获单个属性及其值。

55.组上的量词

将量词直接应用于组(例如,(ab)+ 匹配一个或多个 'ab' 序列)。

56.匹配十六进制颜色

设计模式匹配 HTML 中的十六进制颜色代码。

import re
def extract_hex_color_codes(html_text):
    # 匹配十六进制颜色代码的正则表达式模式
    pattern = re.compile(r'#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b')
    # 在文本中查找所有颜色代码
    color_codes = pattern.findall(html_text)
    # 打印匹配的颜色代码
    print("十六进制颜色代码:")
    for color_code in color_codes:
        print(color_code)
# 测试用例
sample_html = """
<style>
    .background-color {
        background-color: #aabbcc;
    }
    .text-color {
        color: #123;
    }
</style>
"""
extract_hex_color_codes(sample_html)
pattern 正则表达式匹配短格式(#abc)或长格式(#aabbcc)的十六进制颜色代码。

(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})

(?: ... ):非捕获组。

[0-9a-fA-F]{3}:匹配三位十六进制数字。

|:选择。

[0-9a-fA-F]{6}:匹配六位十六进制数字。

此模式将在给定的 HTML 文本中找到所有十六进制颜色代码。请注意,此正则表达式可能还会匹配其他类似十六进制颜色代码的模式。为了更精确地提取,你可以考虑使用专门的 HTML 解析库(如 BeautifulSoup),然后从 style 属性或内联样式中提取颜色代码。

57.验证信用卡有效期

创建正则表达式模式验证信用卡有效期。

import re
from datetime import datetime
def validate_credit_card_expiry(expiry_date):
    # 验证 MM/YY 或 MM/YYYY 格式的信用卡有效期的正则表达式模式
    pattern = re.compile(r'^(0[1-9]|1[0-2])/(20\d{2}|[3-9]\d)$')
    # 检查日期是否匹配模式
    ifnot pattern.match(expiry_date):
        returnFalse
    # 从日期中提取月份和年份
    month, year = map(int, expiry_date.split('/'))
    # 处理年份(如果是两位数)
    if year < 100:
        year += 2000
    # 检查日期是否在未来
    current_date = datetime.now()
    expiry_date = datetime(year, month, 1)
    return expiry_date > current_date
# 测试用例
expiry_dates = [
    "12/23",  # 有效
    "06/2024",  # 有效
    "13/25",  # 无效(月份超过12)
    "01/2000",  # 无效(已过期)
    "MM/YY",  # 无效(格式无效)
]
for expiry_date in expiry_dates:
    if validate_credit_card_expiry(expiry_date):
        print(f"{expiry_date} 是有效的信用卡有效期。")
    else:
        print(f"{expiry_date} 不是有效的信用卡有效期。")
pattern 正则表达式验证 MM/YY 或 MM/YYYY 格式的日期。

^(0[1-9]|1[0-2]):匹配 MM 格式的月份(01 到 12)。

/:匹配分隔符。

(20\d{2}|[3-9]\d)$:匹配 YYYY 格式(以 20 开头)或 YY 格式(以 3-9 开头)的年份。

Python 代码随后检查日期是否在未来。

请注意,虽然正则表达式可以执行基本验证,但必须基于实际日期执行额外检查以确保准确性。对于更可靠的日期处理,考虑使用 dateutil.parser 等日期解析库。

58.匹配函数调用

设计正则表达式模式匹配代码中的函数调用。

import re
def extract_function_calls(code_text):
    # 匹配函数调用的正则表达式模式
    pattern = re.compile(r'\b([a-zA-Z_]\w*)\s*\([^)]*\)')
    # 在文本中查找所有函数调用
    matches = pattern.findall(code_text)
    # 打印匹配的函数调用
    print("函数调用:")
    for match in matches:
        print(match)
# 测试用例
sample_code = """
def hello_world():
    print("Hello, World!")
result = add_numbers(5, 7) + multiply(3, 4)
"""
extract_function_calls(sample_code)
pattern 正则表达式捕获函数调用,包含以下组件:

\b:单词边界,确保匹配完整的函数名。

([a-zA-Z_]\w*):捕获函数名(以字母或下划线开头,后跟字母、数字或下划线)。

\s*:匹配可选空格。

\(:匹配函数调用的左括号。

[^)]*:匹配除右括号外的任何字符,允许包含参数。

\):匹配函数调用的右括号。

59.匹配 SQL 查询

创建模式匹配文本中的 SQL 查询。

import re
def extract_sql_queries(text):
    # 匹配 SQL 查询的正则表达式模式
    pattern = re.compile(r'\b(SELECT|INSERT|UPDATE|DELETE|CREATE|ALTER|DROP|FROM|JOIN|WHERE|ORDER BY|GROUP BY|HAVING|LIMIT|AND|OR|IN|SET|VALUES|INTO|AS|ON|INNER|LEFT|RIGHT|OUTER)\b', re.IGNORECASE)
    # 在文本中查找所有 SQL 关键字
    matches = pattern.findall(text)
    # 打印匹配的 SQL 查询
    print("SQL 关键字:")
    for match in matches:
        print(match)
# 测试用例
sample_text = """
SELECT * FROM employees WHERE department = 'IT';
INSERT INTO customers (name, email) VALUES ('John Doe', 'john@example.com');
UPDATE products SET price = 29.99 WHERE category = 'Electronics';
"""
extract_sql_queries(sample_text)
pattern 正则表达式捕获常见的 SQL 关键字,如 SELECT、INSERT、UPDATE、DELETE 等。

\b:单词边界,确保匹配完整的关键字。

re.IGNORECASE:标志用于使模式不区分大小写。

这是一个基本示例,可能无法覆盖所有 SQL 变体。对于更复杂的场景(如处理嵌套查询或注释),可能需要更复杂的解析器。对于更准确的 SQL 解析,考虑使用专门的 SQL 解析库或工具。

60.匹配 XML 标签

设计模式匹配并提取 XML 标签之间的内容。

import re
def extract_xml_content(xml_text, tag_name):
    # 匹配并提取 XML 标签之间内容的正则表达式模式
    pattern = re.compile(rf'<{tag_name}[^>]*>(.*?)<\/{tag_name}>', re.DOTALL)
    # 在文本中查找所有匹配项
    matches = pattern.findall(xml_text)
    # 打印提取的内容
    print(f"<{tag_name}> 标签之间的内容:")
    for match in matches:
        print(match.strip())
# 测试用例
sample_xml = """
<book>
    <title>Introduction to XML</title>
    <author>John Doe</author>
    <content>
        This is a sample book about XML.
    </content>
</book>
"""
extract_xml_content(sample_xml, 'title')
extract_xml_content(sample_xml, 'content')
该模式用于捕获指定 XML 标签之间的内容。

rf'<{tag_name}[^>]*>(.*?)<\/{tag_name}>':通过 f 字符串动态插入标签名,匹配开始标签 <tag_name> 与对应结束标签 </tag_name> 之间的内容。

re.DOTALL 标志使正则表达式中的 . 能匹配包括换行符在内的所有字符。

需注意,此示例适用于无嵌套标签的简单场景。对于复杂 XML 解析,建议使用 ElementTree 或 lxml 等专用 XML 解析库,它们能更精准地处理 XML 结构。

若 XML 的开始标签包含属性,可调整模式以适配,例如用 (\w+)\s*=\s*["']([^"']*)["'] 捕获属性名和属性值。

若 XML 包含命名空间前缀,可使用适配模式(如 (\w+:)?(\w+))同时捕获命名空间前缀和本地名称。

61.匹配句子

创建模式匹配文本中的完整句子。

import re
def extract_sentences(text):
    # 匹配英文完整句子的正则表达式模式
    pattern = re.compile(r'(?<!\w\.\w.)(?<![A-Z][a-z]\.)(?<=\.|\?)\s')
    # 按模式将文本拆分为句子
    sentences = re.split(pattern, text)
    # 打印提取的句子
    print("提取的句子:")
    for sentence in sentences:
        print(sentence.strip())
# 测试用例
sample_text = """
This is the first sentence. It contains multiple words.
The second sentence has more words. It also ends with a period.
A third sentence exists as well, with a question mark at the end?
"""
extract_sentences(sample_text)
该模式通过正向后顾检测句子结尾的标点(. 或 ?)及后续空白。

(?<!\w\.\w.):负向后顾,排除 "Mr." 等缩写。

(?<![A-Z][a-z]\.):负向后顾,排除句尾常见缩写。

(?<=\.|\?):正向后顾,匹配句号或问号后跟空白的情况。

需注意,此示例无法覆盖所有复杂文本场景。对于高级句子提取,建议使用 spaCy 或 NLTK 等自然语言处理库,它们专为处理语言结构设计。

62.提取 HTML 注释

设计模式提取 HTML 注释内的内容。

import re
def extract_html_comments(html_text):
    # 匹配并提取 HTML 注释内内容的正则表达式模式
    pattern = re.compile(r'<!--(.*?)-->', re.DOTALL)
    # 在文本中查找所有匹配项
    matches = pattern.findall(html_text)
    # 打印提取的内容
    print("HTML 注释内的内容:")
    for match in matches:
        print(match.strip())
# 测试用例
sample_html = """<!DOCTYPE html><html><head>
    <title>HTML Comments Example</title></head><body>
    <!-- This is a comment -->
    <p>This is a paragraph.</p>
    <!-- Another comment
    spanning multiple lines -->
    <div>
        <p>More content</p>
    </div></body></html>
"""
extract_html_comments(sample_html)
pattern 正则表达式使用非贪婪匹配 (.*?) 捕获 <!-- 和 --> 之间的内容。

re.DOTALL:标志使正则表达式中的点(.)匹配包括换行符在内的所有字符。

需要注意的是,虽然此示例在简单场景下可行,但使用正则表达式解析 HTML 注释可能无法覆盖所有边缘情况。对于更可靠的 HTML 解析,建议使用 Python 中的 BeautifulSoup 或 lxml 等专用 HTML 解析库,这些库专为处理 HTML 结构的复杂性而设计,能提供更可靠的 HTML 文档解析方案。

63.匹配浮点数

创建正则表达式模式匹配浮点数。

import re
def extract_float_numbers(text):
    # 匹配浮点数的正则表达式模式
    pattern = re.compile(r'-?\b(?:\d+\.\d*|\.\d+|\d+)(?:[eE][-+]?\d+)?\b')
    # 在文本中查找所有匹配项
    matches = pattern.findall(text)
    # 打印提取的浮点数
    print("提取的浮点数:")
    for match in matches:
        print(match)
# 测试用例
sample_text = """
文本中的数字:3.14、-0.5、123.456、.789、1.2e3、-4.56E-7
非数字:abc、1.2.3、1e、1E2.5
"""
extract_float_numbers(sample_text)
pattern 正则表达式捕获多种格式的浮点数,各部分含义如下:

-?:可选的负号,用于匹配负数。

\b:单词边界,确保匹配完整的数字。

(?:\d+\.\d*|\.\d+|\d+):用于匹配三种情况的分组:

\d+\.\d*:带整数部分且小数部分可选的十进制数。

\.\d+:以小数点开头的十进制数。

\d+:无小数点的整数部分。

(?:[eE][-+]?\d+)?:可选的指数部分,形式为 e 或 E 后跟可选符号及数字。

64.验证 MAC 地址

设计正则表达式模式验证 MAC 地址。

import re
def validate_mac_address(mac_address):
    # 验证 MAC 地址的正则表达式模式
    pattern = re.compile(r'^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$')
    # 检查 MAC 地址是否匹配模式
    return bool(pattern.match(mac_address))
# 测试用例
mac_addresses = [
    "00:1a:2b:3c:4d:5e",
    "01-23-45-67-89-ab",
    "a1:b2:c3:d4:e5:f6",
    "invalid_mac",
]
for mac_address in mac_addresses:
    if validate_mac_address(mac_address):
        print(f"{mac_address} 是有效的 MAC 地址。")
    else:
        print(f"{mac_address} 不是有效的 MAC 地址。")
pattern 正则表达式验证格式为 XX:XX:XX:XX:XX:XX 或 XX-XX-XX-XX-XX-XX 的 MAC 地址,其中 X 为十六进制数字(0-9、A-F、a-f)。

^:匹配字符串的开头。

([0-9A-Fa-f]{2}[:-]){5}:匹配五组两位十六进制数字后跟冒号或连字符的组合。

([0-9A-Fa-f]{2}):匹配最后一组两位十六进制数字。

$:匹配字符串的结尾。

此模式确保 MAC 地址由六组两位十六进制数字组成,各组之间用冒号或连字符分隔。可根据特定的 MAC 地址要求或格式变体进行调整。

65.验证 URL

使用正则表达式模式验证带可选协议的 URL。

import re
def validate_url(url):
    # 验证带可选协议的 URL 的正则表达式模式
    pattern = re.compile(r'^(?:(?:https?|ftp):\/\/)?[^\s\/$.?#].[^\s]*$')
    # 检查 URL 是否匹配模式
    return bool(pattern.match(url))
# 测试用例
urls = [
    "http://www.example.com",
    "https://example.com/path/to/page",
    "ftp://ftp.example.net",
    "www.example.org",
    "invalid url",
]
for url in urls:
    if validate_url(url):
        print(f"{url} 是有效的 URL。")
    else:
        print(f"{url} 不是有效的 URL。")
pattern 正则表达式验证带可选协议的 URL,各部分含义如下:

^(?:(?:https?|ftp):\/\/)?:可选的非捕获组,用于匹配协议(http、https 或 ftp)及后跟的 "://"。

[^\s\/$.?#].[^\s]*$:匹配 URL 的其余部分,排除空白字符和某些特殊字符。

66.匹配社会安全号码

设计模式匹配并提取社会安全号码。

import re
def extract_social_security_numbers(text):
    # 匹配并提取社会安全号码的正则表达式模式
    pattern = re.compile(r'\b(\d{3}-\d{2}-\d{4})\b')
    # 在文本中查找所有匹配项
    matches = pattern.findall(text)
    # 打印提取的社会安全号码
    print("提取的社会安全号码:")
    for match in matches:
        print(match)
# 测试用例
sample_text = """
文本中的社会安全号码:123-45-6789、987-65-4321
非社会安全号码:123-456-789、123-45-67890
"""
extract_social_security_numbers(sample_text)
pattern 正则表达式捕获格式为 XXX-XX-XXXX 的社会安全号码,其中 X 为数字。

\b:单词边界,确保匹配完整的社会安全号码。

67.提取哈希标签

创建模式从文本中提取哈希标签。

import re
def extract_hashtags(text):
    # 匹配并提取哈希标签的正则表达式模式
    pattern = re.compile(r'\#\w+')
    # 在文本中查找所有匹配项
    matches = pattern.findall(text)
    # 打印提取的哈希标签
    print("提取的哈希标签:")
    for match in matches:
        print(match)
# 测试用例
sample_text = """
这是一条带 #sample 文本和 #hashtags 的内容。
#DataScience 和 #MachineLearning 是有趣的话题。
这里没有哈希标签。
"""
extract_hashtags(sample_text)
pattern 正则表达式捕获以 '#' 符号开头,后跟一个或多个单词字符(\w+)的哈希标签。

\#:匹配 '#' 符号。

\w+:匹配一个或多个单词字符(字母、数字或下划线)。

68.匹配 Python 文档字符串

创建模式匹配代码中的 Python 文档字符串。

import re
def extract_python_docstrings(code):
    # 匹配 Python 文档字符串的正则表达式模式
    pattern = re.compile(r'(\'\'\'|\"\"\".*?\'\'\'|\"\"\".*?\"\"\")', re.DOTALL)
    # 在代码中查找所有匹配项
    matches = pattern.findall(code)
    # 打印提取的 Python 文档字符串
    print("提取的 Python 文档字符串:")
    for match in matches:
        print(match)
# 测试用例
sample_code = """
def example_function():
    '''
    这是示例函数的文档字符串。
    它可以跨多行。
    '''
    pass
class ExampleClass:
    \"\"\"
    ExampleClass 的文档字符串。
    它提供了关于该类的信息。
    \"\"\"
    def __init__(self):
        pass
"""
extract_python_docstrings(sample_code)
pattern 正则表达式捕获用三重单引号或三重双引号(''' 或 """)括起来的文档字符串。re.DOTALL 标志用于使正则表达式中的点(.)匹配包括换行符在内的所有字符。

此正则表达式模式提供了一种捕获 Python 文档字符串的基本方法,但需要注意的是,Python 文档字符串的格式多样(例如,可能带或不带三重引号、使用单引号或双引号等)。对于更可靠的解决方案,可考虑使用 ast 等专用的 Python 解析器或库从代码中提取文档字符串。

69.匹配 Markdown 标题

设计正则表达式模式匹配 Markdown 标题。

import re
def extract_markdown_headings(markdown_text):
    # 匹配不同级别 Markdown 标题的正则表达式模式
    heading_patterns = [
        re.compile(r'^#\s(.+)$', re.MULTILINE),      # 一级标题
        re.compile(r'^##\s(.+)$', re.MULTILINE),     # 二级标题
        re.compile(r'^###\s(.+)$', re.MULTILINE),    # 三级标题
        re.compile(r'^####\s(.+)$', re.MULTILINE),   # 四级标题
        re.compile(r'^#####\s(.+)$', re.MULTILINE),  # 五级标题
        re.compile(r'^######\s(.+)$', re.MULTILINE)  # 六级标题
    ]
    # 在文本中查找每个级别标题的所有匹配项
    for i, pattern in enumerate(heading_patterns, start=1):
        matches = pattern.findall(markdown_text)
        print(f"提取的 {i} 级标题:")
        for match in matches:
            print(match)
# 测试用例
sample_markdown = """
# 一级标题
## 二级标题
### 三级标题
#### 四级标题
##### 五级标题
###### 六级标题
非标题:
- 项目符号
"""
extract_markdown_headings(sample_markdown)
这些正则表达式模式使用 ^ 匹配行的开头,通过相应数量的 # 符号加空格来识别不同级别的标题。

(.+)$ 捕获标题的内容。

70.验证十六进制颜色代码

使用正则表达式模式验证十六进制颜色代码。

import re
def validate_hex_color_code(color_code):
    # 验证十六进制颜色代码的正则表达式模式
    pattern = re.compile(r'^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$')
    # 检查颜色代码是否匹配模式
    return bool(pattern.match(color_code))
# 测试用例
color_codes = [
    "#123456",
    "#abc",
    "#fff",
    "#invalid",
]
for color_code in color_codes:
    if validate_hex_color_code(color_code):
        print(f"{color_code} 是有效的十六进制颜色代码。")
    else:
        print(f"{color_code} 不是有效的十六进制颜色代码。")
pattern 正则表达式验证形式为 #RRGGBB 或 #RGB 的十六进制颜色代码,其中 R、G、B 为十六进制数字。

^#:匹配字符串的开头和 '#' 符号。

([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}):匹配六位或三位十六进制数字。

$:匹配字符串的结尾。

71.匹配时间格式

创建模式匹配 HH:MM:SS、HH:MM 格式的时间以及带 AM/PM 的变体形式。

import re
def extract_times(text):
    # 匹配不同格式时间的正则表达式模式
    time_patterns = [
        re.compile(r'\b([01]?[0-9]|2[0-3]):([0-5][0-9])(?::([0-5][0-9]))?\b'),  # HH:MM:SS 或 HH:MM
        re.compile(r'\b([01]?[0-9]|2[0-3]):([0-5][0-9])\s*([AaPp][Mm])?\b')      # HH:MM AM/PM
    ]
    # 在文本中查找每种时间模式的所有匹配项
    for i, pattern in enumerate(time_patterns, start=1):
        matches = pattern.findall(text)
        print(f"提取的时间(格式 {i}):")
        for match in matches:
            print(":".join(filter(None, match)))
# 测试用例
sample_text = """
文本中的时间:12:34、23:45:56、9:15 AM、6:30 PM、18:45
非时间:25:67、3:72、10:00 XYZ
"""
extract_times(sample_text)
第一种模式匹配 HH:MM:SS 或 HH:MM 格式的时间:

\b:单词边界,确保匹配完整的时间。

([01]?[0-9]|2[0-3]):匹配小时(00 到 23)。

([0-5][0-9]):匹配分钟(00 到 59)。

(?::([0-5][0-9]))?:可选地匹配以 :SS 形式表示的秒。

第二种模式匹配 HH:MM AM/PM 格式的时间:

([01]?[0-9]|2[0-3]):匹配小时(00 到 23)。

([0-5][0-9]):匹配分钟(00 到 59)。

\s*([AaPp][Mm])?:可选地匹配 AM 或 PM。

72.匹配嵌套括号

设计模式匹配带指定深度嵌套括号的表达式。

import re
def extract_nested_brackets(text, depth):
    # 匹配带指定深度嵌套括号的表达式的正则表达式模式
    pattern = re.compile(rf'\((?:[^()]*|\((?:[^()]*|\((?:[^()]*|\((?:[^()]*|\([^()]*\))*\))*\))*\)){{{depth}}}\)')
    # 在文本中查找所有匹配项
    matches = pattern.findall(text)
    # 打印提取的带嵌套括号的表达式
    print("提取的带嵌套括号的表达式:")
    for match in matches:
        print(match)
# 测试用例
sample_text = """
带嵌套括号的表达式:(a + (b * c) - d)
另一个表达式:((x + y) / z) * (m - n)
过深的表达式:(((p + q) - r) * s) / t
"""
# 指定要匹配的嵌套括号深度
nested_depth = 2
extract_nested_brackets(sample_text, nested_depth)
pattern 正则表达式尝试匹配嵌套括号深度不超过指定值的表达式。

\( ... \):匹配一对括号。

(?: ... ):用于分组但不捕获的非捕获组。

[^()]*:匹配零个或多个除 '(' 和 ')' 之外的字符。

\((?:[^()]*|\((?:[^()]*|\((?:[^()]*|\((?:[^()]*|\([^()]*\))*\))*\))*\)):匹配嵌套深度不超过指定值的括号。

需要注意的是,正则表达式并非解析括号等嵌套结构的最佳工具,尤其是当深度不固定时。对于更复杂的场景,可能需要使用解析器或更高级的方法。

阅读原文

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Python 正则表达式 文本处理 re模块 编程技巧
相关文章