学研妹 2025-08-14 17:38 浙江
掌握 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) # Noneresult = 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 redef 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 redef 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 redef 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 redef 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 redef 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 redef 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 redef 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 redef 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 redef 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 redef 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 redef 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 redef 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 redef 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."""# 从文本中提取 URLextract_urls(text_with_urls)
https?
:匹配 "http" 或 "https"。
://
:匹配 "://"。
\S+
:匹配一个或多个非空白字符(域名)。
|
:或运算符。
www\.\S+
:匹配 "www." 后跟一个或多个非空白字符。
模式2:扩展 URL 提取
import redef 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."""# 从文本中提取 URLextract_urls_extended(text_with_urls_extended)
(?:www\.)?
:可选 "www." 的非捕获组。
(?:\?\S+)?)
:可选查询参数(以 "?" 开头)的非捕获组。
32.匹配 HTML 实体
使用正则表达式匹配或替换 HTML 实体。
import refrom html import unescapedef 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 redef 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 redef 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 redef 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 redef 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 redef 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.1Server 2: 10.0.0.255Invalid 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 redef 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.1Server 2: 10.0.0.255Invalid 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 redef 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 redef 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 redef 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 redef 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 regexdef 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 redef 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 redef 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 redef 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 redef 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 redef 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 redef 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 redef 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 refrom datetime import datetimedef 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 redef 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 redef 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 redef 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 redef 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 redef 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 redef 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 redef 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 redef 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 redef 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 redef 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 redef 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(): ''' 这是示例函数的文档字符串。 它可以跨多行。 ''' passclass ExampleClass: \"\"\" ExampleClass 的文档字符串。 它提供了关于该类的信息。 \"\"\" def __init__(self): pass"""extract_python_docstrings(sample_code)
pattern
正则表达式捕获用三重单引号或三重双引号(''' 或 """)括起来的文档字符串。re.DOTALL
标志用于使正则表达式中的点(.)匹配包括换行符在内的所有字符。
此正则表达式模式提供了一种捕获 Python 文档字符串的基本方法,但需要注意的是,Python 文档字符串的格式多样(例如,可能带或不带三重引号、使用单引号或双引号等)。对于更可靠的解决方案,可考虑使用 ast
等专用的 Python 解析器或库从代码中提取文档字符串。
69.匹配 Markdown 标题
设计正则表达式模式匹配 Markdown 标题。
import redef 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 redef 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 redef 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 redef 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 = 2extract_nested_brackets(sample_text, nested_depth)
pattern
正则表达式尝试匹配嵌套括号深度不超过指定值的表达式。
\( ... \)
:匹配一对括号。
(?: ... )
:用于分组但不捕获的非捕获组。
[^()]*
:匹配零个或多个除 '(' 和 ')' 之外的字符。
\((?:[^()]*|\((?:[^()]*|\((?:[^()]*|\((?:[^()]*|\([^()]*\))*\))*\))*\))
:匹配嵌套深度不超过指定值的括号。
需要注意的是,正则表达式并非解析括号等嵌套结构的最佳工具,尤其是当深度不固定时。对于更复杂的场景,可能需要使用解析器或更高级的方法。