PYTHON基础技能 – Python中利用正则表达式的16个常见任务
1. 正则表达式是什么?
正则表达式是一种用于匹配字符串的语言。它由一系列字符和特殊符号组成,用来描述搜索模式。在Python中,re模块提供了支持正则表达式的功能。
2. 安装与导入
首先,确保你的Python环境中已经安装了re模块。这是Python的标准库之一,所以通常不需要额外安装。
import re
3. 字符匹配
- 单个字符:使用方括号
[]表示一组字符中的任意一个。
# 匹配任何字母
pattern = "[a-zA-Z]"
string = "Hello World!"
match = re.search(pattern, string)
print(match.group()) # 输出: H
- 多个字符:使用
*表示零次或多次出现。
# 匹配任意数量的空格
pattern = "\s*"
string = " Hello World!"
match = re.match(pattern, string)
print(match.group()) # 输出: ' '
4. 范围匹配
- 使用
-定义一个范围内的字符。
# 匹配小写字母a到e
pattern = "[a-e]"
string = "abcdeABCDE"
matches = re.findall(pattern, string)
print(matches) # 输出: ['a', 'b', 'c', 'd', 'e']
5. 排除字符
- 使用
^排除某些字符。
# 匹配除了a到z之外的所有字符
pattern = "[^a-z]"
string = "123ABCdef"
matches = re.findall(pattern, string)
print(matches) # 输出: ['1', '2', '3', 'A', 'B', 'C']
6. 字符集组合
- 可以将多个字符集组合起来使用。
# 匹配数字或大写字母
pattern = "[0-9A-Z]+"
string = "Hello123World"
matches = re.findall(pattern, string)
print(matches) # 输出: ['123']
7. 位置锚定
^表示行首,$表示行尾。
# 匹配以大写字母开头的单词
pattern = "^[A-Z][a-zA-Z]*"
string = "Hello world"
matches = re.findall(pattern, string)
print(matches) # 输出: ['Hello']
8. 分组与引用
- 使用圆括号
()来创建一个捕获组。
# 捕获日期格式
pattern = "(\d{4})-(\d{2})-(\d{2})"
string = "Today is 2023-04-01."
match = re.match(pattern, "2023-04-01")
if match:
year = match.group(1)
month = match.group(2)
day = match.group(3)
print(f"Year: {year}, Month: {month}, Day: {day}")
9. 非捕获组
- 如果不关心某部分的内容,可以使用
(?:)。
# 不捕获中间的冒号
pattern = r"(\d{2}):(?:\d{2}):\d{2}"
string = "09:30:15"
match = re.match(pattern, string)
if match:
hour = match.group(1)
print(hour) # 输出: 09
10. 替换文本
- 使用
re.sub()方法替换字符串中的匹配项。
# 将所有空格替换成下划线
pattern = "\s+"
string = "Hello World"
new_string = re.sub(pattern, "_", string)
print(new_string) # 输出: Hello_World
11. 贪婪与非贪婪匹配
- 贪婪匹配:默认情况下,正则表达式会尽可能多地匹配字符。
- 非贪婪匹配:使用
?使匹配变得“懒惰”,即尽可能少地匹配字符。
# 贪婪匹配
pattern = "<.*>"
string = "<p>Hello <span>World</span></p>"
match = re.search(pattern, string)
print(match.group()) # 输出: <p>Hello <span>World</span></p>
# 非贪婪匹配
pattern = "<.*?>"
string = "<p>Hello <span>World</span></p>"
match = re.search(pattern, string)
print(match.group()) # 输出: <p>
12. 条件分支
- 使用
(?P<name>)命名捕获组,并通过(?P=name)引用它们。
# 匹配重复的单词
pattern = r"\b(\w+)\b\s+\1\b"
string = "hello hello world"
match = re.sub(pattern, r"\1", string, flags=re.IGNORECASE)
print(match) # 输出: hello world
13. 重复限定符
- 使用
{n}指定精确重复次数。 - 使用
{n,}指定至少重复n次。 - 使用
{n,m}指定重复n到m次。
# 匹配恰好重复三次的字符
pattern = r"a{3}"
string = "aaabbbccc"
matches = re.findall(pattern, string)
print(matches) # 输出: []
# 匹配至少重复两次的字符
pattern = r"a{2,}"
string = "aaabbbccc"
matches = re.findall(pattern, string)
print(matches) # 输出: ['aaa']
# 匹配重复两到四次的字符
pattern = r"a{2,4}"
string = "aaabbbccc"
matches = re.findall(pattern, string)
print(matches) # 输出: ['aaa']
14. 特殊字符
- 点号
.:匹配除换行符之外的任何字符。 - 反斜杠
\:转义特殊字符。
# 匹配包含任何字符的单词
pattern = r"\w+"
string = "hello\nworld"
matches = re.findall(pattern, string)
print(matches) # 输出: ['hello']
# 匹配特殊字符
pattern = r"\."
string = "hello.world"
matches = re.findall(pattern, string)
print(matches) # 输出: ['.']
15. 边界限定符
- 单词边界
\b:匹配单词的开始和结束。 - 非单词边界
\B:匹配非单词的位置。
# 匹配单词边界
pattern = r"\bhello\b"
string = "hello world"
matches = re.findall(pattern, string)
print(matches) # 输出: ['hello']
# 匹配非单词边界
pattern = r"\Bworld\B"
string = "hello world"
matches = re.findall(pattern, string)
print(matches) # 输出: []
16. 标志位
- 忽略大小写
re.IGNORECASE:使匹配不区分大小写。 - 多行模式
re.MULTILINE:使^和$分别匹配每一行的开始和结束。 - 点号匹配换行符
re.DOTALL:使.匹配包括换行符在内的任何字符。
# 忽略大小写
pattern = r"hello"
string = "Hello world"
matches = re.findall(pattern, string, re.IGNORECASE)
print(matches) # 输出: ['Hello']
# 多行模式
pattern = r"^hello"
string = "hello\nworld"
matches = re.findall(pattern, string, re.MULTILINE)
print(matches) # 输出: ['hello']
# 点号匹配换行符
pattern = r"hello.*world"
string = "hello\nworld"
matches = re.findall(pattern, string, re.DOTALL)
print(matches) # 输出: ['hello\nworld']
实战案例分析
假设我们需要从一段文本中提取所有的邮箱地址。这可以通过正则表达式轻松实现。邮箱地址的一般形式为 username@domain.com。下面是一个简单的示例:
# 提取邮箱地址
pattern = r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
string = """
John Doe <johndoe@example.com>
Jane Smith <janesmith@company.org>
"""
matches = re.findall(pattern, string)
print(matches) # 输出: ['johndoe@example.com', 'janesmith@company.org']