正则表达式是一种强大的工具,可以用来匹配、查找、替换字符串中的特定模式。Python 的 re
模块提供了对正则表达式的支持。本文将带你从基础到进阶,逐步了解如何使用 Python 正则表达式进行文本匹配。
1. 导入 re 模块
首先,我们需要导入 Python 的 re
模块。这是使用正则表达式的前提。
import re
2. 基本匹配
最简单的正则表达式就是直接匹配一个固定的字符串。例如,我们想在一个字符串中查找单词 "hello"。
text = "Hello, world! Hello again."
pattern = "hello"
# 使用 re.search() 查找第一个匹配项
match = re.search(pattern, text, re.IGNORECASE) # re.IGNORECASE 表示忽略大小写
if match:
print("找到匹配项:", match.group())
else:
print("没有找到匹配项")
输出:
找到匹配项: Hello
3. 匹配多个字符
正则表达式中的点号 .
可以匹配任何单个字符(除了换行符)。例如,我们想匹配一个三个字符的单词,其中第二个字符可以是任意字符。
text = "cat bat rat mat"
pattern = "c.t"
matches = re.findall(pattern, text)
print("所有匹配项:", matches)
输出:
所有匹配项: ['cat']
4. 匹配字符集
方括号 []
可以用来定义一个字符集,表示匹配其中的任何一个字符。例如,我们想匹配 "a" 或 "e" 开头的单词。
text = "apple elephant antelope"
pattern = "[ae]pple"
matches = re.findall(pattern, text)
print("所有匹配项:", matches)
输出:
所有匹配项: ['apple']
5. 匹配范围
我们可以使用连字符 -
来定义一个字符范围。例如,匹配所有小写字母。
text = "abc123 def456 ghi789"
pattern = "[a-z]+"
matches = re.findall(pattern, text)
print("所有匹配项:", matches)
输出:
所有匹配项: ['abc', 'def', 'ghi']
6. 匹配重复
量词 {m,n}
可以用来指定匹配次数的范围。例如,匹配至少两个 "a" 的单词。
text = "aa bb aaa ccc aaaa"
pattern = "a{2,}"
matches = re.findall(pattern, text)
print("所有匹配项:", matches)
输出:
所有匹配项: ['aa', 'aaa', 'aaaa']
7. 匹配零次或多次
星号 *
表示匹配前面的字符零次或多次。例如,匹配 "ab" 后面可能跟着任意数量的 "c"。
text = "abc abccc ab abcccc"
pattern = "abc*"
matches = re.findall(pattern, text)
print("所有匹配项:", matches)
输出:
所有匹配项: ['abc', 'abccc', 'ab', 'abcccc']
8. 匹配一次或多次
加号 +
表示匹配前面的字符一次或多次。例如,匹配 "ab" 后面至少有一个 "c"。
text = "abc abccc ab abcccc"
pattern = "abc+"
matches = re.findall(pattern, text)
print("所有匹配项:", matches)
输出:
所有匹配项: ['abc', 'abccc', 'abcccc']
9. 匹配零次或一次
问号 ?
表示匹配前面的字符零次或一次。例如,匹配 "ab" 后面可能有一个 "c"。
text = "abc ab abcc"
pattern = "abc?"
matches = re.findall(pattern, text)
print("所有匹配项:", matches)
输出:
所有匹配项: ['abc', 'ab', 'abc']
10. 分组
圆括号 ()
可以用来分组,方便提取特定部分。例如,提取日期中的年份、月份和日。
text = "Today is 2023-10-05"
pattern = "(\d{4})-(\d{2})-(\d{2})"
match = re.search(pattern, text)
if match:
year, month, day = match.groups()
print(f"年份: {year}, 月份: {month}, 日: {day}")
else:
print("没有找到匹配项")
输出:
年份: 2023, 月份: 10, 日: 05
11. 非捕获分组
非捕获分组 (?:...)
不会捕获匹配的子字符串。例如,匹配 "http" 或 "https"。
text = "Visit https://example.com or http://example.org"
pattern = "(?:https?://)([a-zA-Z0-9.-]+)"
matches = re.findall(pattern, text)
print("所有匹配项:", matches)
输出:
所有匹配项: ['example.com', 'example.org']
12. 贪婪与非贪婪匹配
默认情况下,量词是贪婪的,会尽可能多地匹配。使用 ?
可以使其变为非贪婪模式。例如,匹配 HTML 标签。
text = "<b>bold</b> and <i>italic</i>"
pattern = "<.*>"
greedy_matches = re.findall(pattern, text)
non_greedy_matches = re.findall("<.*?>", text)
print("贪婪匹配:", greedy_matches)
print("非贪婪匹配:", non_greedy_matches)
输出:
贪婪匹配: ['<b>bold</b> and <i>italic</i>']
非贪婪匹配: ['<b>', '</b>', '<i>', '</i>']
13. 替换字符串
使用 re.sub()
可以替换匹配的字符串。例如,将所有的空格替换为下划线。
text = "Hello World This Is A Test"
pattern = " "
new_text = re.sub(pattern, "_", text)
print("替换后的字符串:", new_text)
输出:
替换后的字符串: Hello_World_This_Is_A_Test
14. 实战案例:提取电子邮件地址
假设我们有一个包含多个电子邮件地址的文本文件,我们需要提取所有的电子邮件地址。
text = """
Contact us at support@example.com for any inquiries.
You can also reach out to sales@example.net or info@example.org.
"""
# 定义电子邮件地址的正则表达式
pattern = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z]{2,}\b"
# 提取所有电子邮件地址
emails = re.findall(pattern, text, re.IGNORECASE)
print("提取的电子邮件地址:", emails)
输出:
提取的电子邮件地址: ['support@example.com', 'sales@example.net', 'info@example.org']
总结
本文介绍了如何使用 Python 正则表达式进行文本匹配,从基本的字符串匹配到复杂的模式匹配,再到实际的应用案例。
好了,今天的分享就到这里了,我们下期见。如果本文对你有帮助,请动动你可爱的小手指点赞、转发、在看吧!
付费合集推荐
文末福利
公众号消息窗口回复“编程资料”,获取Python编程、人工智能、爬虫等100+本精品电子书。