Python正则表达式:文本处理的强大工具
嗨,小伙伴们!今天我们要一起探索Python中一个非常强大但有时也让人感到神秘的功能 —— 正则表达式。正则表达式就像是文本处理的瑞士军刀,可以帮助我们进行复杂的字符串匹配、搜索和替换操作。虽然乍看起来可能有点intimidating,但别担心,我们会一步步掌握这个强大的工具!
1. 正则表达式初探
我们需要导入Python的
re
模块,它提供了所有与正则表达式相关的功能:
```python
import re
让我们从一个简单的例子开始:
python
复制
pattern = r'\d+' # 匹配一个或多个数字
text = “我今年25岁,身高180cm”
matches = re.findall(pattern, text)
print(matches) # 输出:['25', '180']
在这个例子中,
\d+
是一个正则表达式模式,它匹配一个或多个数字。
re.findall()
函数会找出所有匹配的子字符串并返回一个列表。
小贴士:在Python中,我们常常在字符串前加
r
(如
r'\d+'
),这表示这是一个“原始字符串”,Python不会对反斜杠进行特殊处理。这在写正则表达式时特别有用!
2. 常用的正则表达式模式
正则表达式有一些常用的特殊字符和模式,让我们来看看:
python
复制
import re
text = “The quick brown fox jumps over the lazy dog. It barked:woof 123!”
# 匹配单词
word_pattern = r'\b\w+\b'
words = re.findall(word_pattern, text)
print(“Words:”, words)
# 匹配邮箱地址
email_pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
email = “Contact us at:[email protected]”
found_email = re.search(email_pattern, email)
print(“Email:”, found_email.group() if found_email else “No email found”)
# 匹配电话号码(简化的美国格式)
phone_pattern = r'\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}'
phone = “Call us at (123) 456-7890 or 987-654-3210”
phone_numbers = re.findall(phone_pattern, phone)
print(“Phone numbers:”, phone_numbers)
这里我们看到了几个常用的模式:
-
\b:单词边界 -
\w+:一个或多个字母、数字或下划线 -
[A-Za-z0-9._%+-]+:一组允许的字符,用于匹配邮箱的用户名部分 -
\d{3}:恰好三个数字
注意事项:正则表达式非常强大,但也可能变得复杂。在处理复杂的模式时,建议将其分解并添加注释,以提高可读性。
3. 使用正则表达式进行替换
除了查找,正则表达式还常用于文本替换:
python
复制
import re
text = “我的电话是123-456-7890和987-654-3210”
# 隐藏电话号码的中间四位数字
hidden_text = re.sub(r'(\d{3})-\d{4}-(\d{4})', r'\1-****-\2', text)
print(hidden_text)
# 输出:我的电话是123-****-7890和987-****-3210
re.sub()
函数用于替换文本。这里我们使用了分组(括号内的部分)来保留我们想保留的部分,并用
\1
和
\2
来引用这些分组。
4. 编译正则表达式
如果你需要多次使用同一个正则表达式,可以先将其编译以提高效率:
python
复制
import re
pattern = re.compile(r'\d+')
text1 = “我今年25岁”
text2 = “我的身高是180cm”
print(pattern.findall(text1)) # 输出:['25']
print(pattern.findall(text2)) # 输出:['180']
编译后的正则表达式对象可以多次使用,而无需每次都重新解析模式。
5. 正则表达式的贪婪vs非贪婪匹配
默认情况下,正则表达式是贪婪的,意味着它们会尽可能多地匹配:
python
复制
import re
text = “<p>这是一个段落</p><p>这是另一个段落</p>”
# 贪婪匹配
greedy_pattern = r'<p>.*</p>'
print(re.findall(greedy_pattern, text))
# 输出:['<p>这是一个段落</p><p>这是另一个段落</p>']
# 非贪婪匹配
non_greedy_pattern = r'<p>.*?</p>'
print(re.findall(non_greedy_pattern, text))
# 输出:['<p>这是一个段落</p>', '<p>这是另一个段落</p>']
通过在
*
或
+
后面加上
?
,我们可以使匹配变成非贪婪的,这在处理HTML等结构化文本时特别有用。
小贴士:在处理HTML时,最好使用专门的HTML解析库(如Beautiful Soup)而不是正则表达式,因为HTML的结构可能非常复杂。
总结
今天我们学习了Python中正则表达式的基础知识,包括基本语法、常用模式、替换操作、编译正则表达式以及贪婪与非贪婪匹配。正则表达式是一个强大的工具,可以大大简化我们的文本处理任务。