正则表达式语法详解
AI-摘要
Chat GPT
AI初始化中...
介绍自己
生成本文简介
推荐相关文章
前往主页
前往tianli博客
本文最后更新于 2025-02-10,墨迹未干时,知识正鲜活。随着时间推移,文章部分内容可能需要重新着墨,请您谅解。Contact
正则表达式语法详解
基本字符
- 普通字符: 大部分字符(字母、数字等)都表示它们自身。例如,
a
匹配字母 "a",1
匹配数字 "1"。 .
(点号): 匹配除换行符 (\n
) 之外的任何单个字符。\
(反斜杠):- 转义字符: 用于匹配特殊字符本身。例如,
\.
匹配点号 ".",\\
匹配反斜杠 ""。 - 特殊序列: 与某些字母结合,表示特定字符类别。例如,
\d
匹配任何数字,\s
匹配任何空白字符。
- 转义字符: 用于匹配特殊字符本身。例如,
字符集
[...]
(方括号): 匹配方括号内的任何一个字符。- 例如:
[abc]
匹配 "a"、"b" 或 "c"。 - 范围表示:
[a-z]
匹配任何小写字母,[0-9]
匹配任何数字。 - 排除字符:
[^abc]
匹配除 "a"、"b" 和 "c" 之外的任何字符。
- 例如:
量词 (Quantifiers)
*
: 匹配前面的字符零次或多次。+
: 匹配前面的字符一次或多次。?
: 匹配前面的字符零次或一次。{n}
: 匹配前面的字符恰好 n 次。{n,}
: 匹配前面的字符至少 n 次。{n,m}
: 匹配前面的字符 n 到 m 次 (包含 n 和 m)。
边界匹配
^
: 匹配字符串的开头。$
: 匹配字符串的结尾。\b
: 匹配单词边界 (单词字符和非单词字符之间的位置)。\B
: 匹配非单词边界。
分组和捕获
(...)
(圆括号):- 分组:将多个字符视为一个整体,可以对分组应用量词。
- 捕获:将括号内匹配的内容保存起来,供后续引用 (通过
\1
,\2
等)。
| 或 (Alternation)
|
: 匹配竖线两侧的任意一个表达式。例如,cat|dog
匹配 "cat" 或 "dog"。
特殊序列
\d
: 匹配任何数字,等价于[0-9]
。\D
: 匹配任何非数字字符,等价于[^0-9]
。\w
: 匹配任何字母、数字或下划线,等价于[a-zA-Z0-9_]
。\W
: 匹配任何非字母、数字或下划线字符,等价于[^a-zA-Z0-9_]
。\s
: 匹配任何空白字符 (空格、制表符、换行符等)。\S
: 匹配任何非空白字符。
Python 中的正则表达式 (re 模块)
Python 的 re
模块提供了对正则表达式的支持。常用的函数:
re.compile(pattern, flags=0)
: 将正则表达式编译成一个模式对象,可以提高匹配效率。re.search(pattern, string, flags=0)
: 在字符串中搜索第一个匹配项,返回一个匹配对象 (match object) 或None
。re.match(pattern, string, flags=0)
: 从字符串的开头开始匹配,返回一个匹配对象或None
。re.findall(pattern, string, flags=0)
: 查找字符串中所有非重叠的匹配项,返回一个列表。re.finditer(pattern, string, flags=0)
: 查找字符串中所有非重叠的匹配项,返回一个迭代器,每个元素是一个匹配对象。re.sub(pattern, repl, string, count=0, flags=0)
: 将字符串中所有匹配的子串替换为repl
(可以是字符串或函数)。re.split(pattern, string, maxsplit=0, flags=0)
: 使用正则表达式作为分隔符来分割字符串。
标志 (Flags)
re
模块的函数通常接受一个可选的 flags
参数,用来修改正则表达式的行为。常用标志:
re.IGNORECASE
(或re.I
): 忽略大小写。re.MULTILINE
(或re.M
): 多行模式,使^
和$
匹配每一行的开头和结尾。re.DOTALL
(或re.S
): 使.
匹配任何字符,包括换行符。
匹配对象 (Match Object)
re.search()
, re.match()
, re.finditer()
返回匹配对象,它包含有关匹配的信息:
group(n=0)
: 返回第 n 个捕获组的文本 (n=0 表示整个匹配)。groups()
: 返回所有捕获组的文本,以元组形式。start(n=0)
: 返回第 n 个捕获组的起始索引。end(n=0)
: 返回第 n 个捕获组的结束索引。span(n=0)
: 返回第 n 个捕获组的起始和结束索引,以元组形式(start, end)
。
Python 文本编辑示例
import re
text = """
This is a sample text with some email addresses:
[email protected], [email protected]
And some phone numbers:
123-456-7890, (555) 123-4567
"""
# 1. 查找所有电子邮件地址
email_pattern = r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
emails = re.findall(email_pattern, text)
print("Emails:", emails) # 输出: ['[email protected]', '[email protected]']
# 2. 查找所有电话号码
phone_pattern = r"(\d{3}[-\s]?\d{3}[-\s]?\d{4}|\(\d{3}\)\s?\d{3}[-\s]?\d{4})" # 两种格式
phones = re.finditer(phone_pattern, text)
print("Phone Numbers:")
for phone in phones:
print(phone.group()) # 输出: 123-456-7890 和 (555) 123-4567
# 3. 将电话号码格式统一为 xxx-xxx-xxxx
def format_phone(match):
num = match.group()
num = re.sub(r"\D", "", num) # 移除所有非数字字符
return f"{num[:3]}-{num[3:6]}-{num[6:]}"
formatted_text = re.sub(phone_pattern, format_phone, text)
print("\nFormatted Text:\n", formatted_text)
# 4. 提取域名
domain_pattern = r"@([a-zA-Z0-9.-]+)\." #用括号提取
domains = []
for email in emails:
match = re.search(domain_pattern, email)
if match:
domains.append(match.group(1)) # 使用 group(1) 获取第一个捕获组
print("\nDomains:", domains) # 输出: ['example.com', 'domain.net']
# 5. 将文本中的所有数字替换为 "NUM"
replaced_text = re.sub(r"\d+", "NUM", text)
print("\nReplaced Text:\n", replaced_text)
#6. HTML 标签提取
html_text = "<p>This is a <b>bold</b> word and <i>italic</i>.</p>"
tag_content_pattern = r"<[^>]+>([^<]+)</[^>]+>" # 匹配标签内的内容
# 或者更简单的非贪婪模式:
# tag_content_pattern = r"<.+?>(.+?)</.+?>"
matches = re.findall(tag_content_pattern, html_text)
print("\nTag Contents:", matches) # 输出:['This is a ', 'bold', ' word and ', 'italic', '.'] 注意,这个例子有局限性,更复杂的 HTML 需要 HTML 解析器
#7. 验证密码强度 (示例)
def is_strong_password(password):
pattern = r"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$"
# 至少 8 个字符
# 至少包含一个小写字母
# 至少包含一个大写字母
# 至少包含一个数字
# 至少包含一个特殊字符
return bool(re.match(pattern, password))
print("\nPassword Strength:")
print("Password123:", is_strong_password("Password123")) # False
print("StrongP@ss1:", is_strong_password("StrongP@ss1")) # True
print("Short1:", is_strong_password("Short1")) # False
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 JackLee
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果