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.IGNORECASE
:re.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.IGNORECASE
:re.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-YYYYimport 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-DDimport 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 YYYYimport 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 * 2, 10)) 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
正则表达式尝试匹配嵌套括号深度不超过指定值的表达式。\( ... \)
:匹配一对括号。(?: ... )
:用于分组但不捕获的非捕获组。[^()]*
:匹配零个或多个除 '(' 和 ')' 之外的字符。\((?:[^()]*|\((?:[^()]*|\((?:[^()]*|\((?:[^()]*|\([^()]*\))*\))*\))*\))
:匹配嵌套深度不超过指定值的括号。需要注意的是,正则表达式并非解析括号等嵌套结构的最佳工具,尤其是当深度不固定时。对于更复杂的场景,可能需要使用解析器或更高级的方法。阅读原文
跳转微信打开