下面介绍正则表达式的基础知识和使用方法。
-
正则表达式是什么?
正则表达式(Regular Expression,简称regex)是一种用于匹配字符串模式的强大工具。就像是一种特殊的搜索语言。 -
Python中使用正则表达式的基本步骤:
import re # 首先导入re模块# 基本使用方法
pattern = r'你要匹配的模式' # r表示原始字符串
text = "要搜索的文本"
result = re.findall(pattern, text) # 查找所有匹配
- 常用的正则表达式语法:
# 基础匹配符号
. → 匹配任意单个字符(除了换行符)
* → 匹配前面的字符0次或多次
+ → 匹配前面的字符1次或多次
? → 匹配前面的字符0次或1次
^ → 匹配字符串的开始
$ → 匹配字符串的结束# 示例1:匹配电话号码
pattern = r'\d{11}' # \d表示数字,{11}表示重复11次
phone = "我的电话是13812345678"
result = re.findall(pattern, phone)
print(result) # ['13812345678']# 示例2:匹配邮箱
pattern = r'\w+@\w+\.\w+' # \w表示字母数字下划线
email = "联系我:test@example.com"
result = re.findall(pattern, email)
print(result) # ['test@example.com']
- 分组和引用(这就是我们AABB模式中用到的):
# ()表示分组,\1表示引用第一个分组
# 示例:匹配重复的字符
pattern = r'(.)(\1)' # 匹配连续重复的任意字符
text = "书书信信"
result = re.findall(pattern, text)
print(result) # [('书', '书'), ('信', '信')]# AABB模式的解释
pattern = r'(.)(\1)(.)(\3)'
# (.) 捕获第一个字符,作为第一个分组
# (\1) 引用第一个分组的内容(必须相同)
# (.) 捕获第三个字符,作为第三个分组
# (\3) 引用第三个分组的内容(必须相同)
- 常用的正则表达式方法:
import retext = "Python编程很有趣"# 查找所有匹配
re.findall(pattern, text) # 返回所有匹配的列表# 查找第一个匹配
re.search(pattern, text) # 返回第一个匹配的对象# 替换匹配的文本
re.sub(pattern, replacement, text) # 返回替换后的字符串# 分割字符串
re.split(pattern, text) # 返回分割后的列表
- 实用小例子:
# 例1:提取所有数字
text = "我今年25岁,电话是13812345678"
numbers = re.findall(r'\d+', text)
print(numbers) # ['25', '13812345678']# 例2:匹配中文字符
text = "Hello你好World世界"
chinese = re.findall(r'[\u4e00-\u9fa5]+', text)
print(chinese) # ['你好', '世界']# 例3:验证简单的邮箱格式
def is_valid_email(email):pattern = r'^[\w\.-]+@[\w\.-]+\.\w+$'return bool(re.match(pattern, email))print(is_valid_email("test@example.com")) # True
print(is_valid_email("invalid.email")) # False
让我们回到AABB模式的例子:
# AABB模式的详细解释
text = "蒙蒙胧胧的天空,匆匆忙忙地走了"
pattern = r'(.)(\1)(.)(\3)'# 分解说明
# (.) 第一个字符(比如'蒙')
# (\1) 重复第一个字符(又一个'蒙')
# (.) 第三个字符(比如'胧')
# (\3) 重复第三个字符(又一个'胧')matches = re.findall(pattern, text)
for match in matches:print(''.join(match)) # 输出:蒙蒙胧胧 匆匆忙忙
这些是正则表达式的基础用法。
正则表达式中常用字符与作用的对照
1. 特殊字符类:
\d → 匹配任意数字 (等同于[0-9])
\D → 匹配任意非数字 (等同于[^0-9])
\w → 匹配字母、数字、下划线 (等同于[a-zA-Z0-9_])
\W → 匹配非字母、数字、下划线 (等同于[^a-zA-Z0-9_])
\s → 匹配任意空白字符(空格、制表符、换行符等)
\S → 匹配任意非空白字符
2. 数量限定符:
* → 匹配前面的字符 0次或多次 (等同于{0,})
+ → 匹配前面的字符 1次或多次 (等同于{1,})
? → 匹配前面的字符 0次或1次 (等同于{0,1})
{n} → 精确匹配 n 次
{n,} → 匹配 n 次或更多次
{n,m} → 匹配 n 到 m 次
3. 边界匹配:
^ → 匹配字符串开头
$ → 匹配字符串结尾
\b → 匹配单词边界
\B → 匹配非单词边界
4. 常用特殊字符:
. → 匹配除换行符外的任意字符
\ → 转义字符
| → 或运算符(选择)
() → 分组
[] → 字符类,匹配其中的任意一个字符
[^] → 否定字符类,匹配除其中字符外的任意字符
5. 实例说明:
# 手机号码匹配
pattern = r'1\d{10}' # 1开头后跟10个数字# 邮箱匹配
pattern = r'\w+@\w+\.\w+' # 若干字母数字_@若干字母数字_.若干字母数字_# 中文匹配
pattern = r'[\u4e00-\u9fa5]' # 匹配一个中文字符# 提取网址
pattern = r'https?://\S+' # http或https开头,后跟://和非空白字符# 匹配日期格式
pattern = r'\d{4}-\d{2}-\d{2}' # 类似2024-03-21的格式
6. 实用组合示例:
import re# 示例1:提取文本中的所有数字
text = "我的电话是13912345678,邮编是100081"
numbers = re.findall(r'\d+', text)
print(numbers) # ['13912345678', '100081']# 示例2:匹配单词
text = "Hello_world Python123 测试"
words = re.findall(r'\w+', text)
print(words) # ['Hello_world', 'Python123']# 示例3:分割字符串
text = "姓名:张三;年龄:25;职业:程序员"
info = re.split(r'[;:]', text)
print(info) # ['姓名', '张三', '年龄', '25', '职业', '程序员']
7. 常见用途表:
用途 | 模式 | 说明 |
---|---|---|
电话号码 | \d{11} | 11位数字 |
简单邮箱 | \w+@\w+\.\w+ | 用户名@域名.顶级域名 |
日期 | \d{4}-\d{2}-\d{2} | 年-月-日格式 |
中文字符 | [\u4e00-\u9fa5] | 匹配单个中文 |
网址 | https?://\S+ | http或https开头的网址 |
邮政编码 | \d{6} | 6位数字 |
记忆技巧:
\d
(digit): 想象成"数字"的首字母\w
(word): 想象成"单词"的首字母\s
(space): 想象成"空格"的首字母- 大写字母(如\D, \W, \S)表示对应小写的反义