无封面
2025-07-31
python正则表达式详解
在Python里,正则表达式是进行字符串模式匹配与操作的有力工具。下面将详细介绍Python正则表达式的相关知识,并且结合实例来加深理解。
1. 基础元字符
元字符是正则表达式里具有特殊含义的字符,下面是一些常用的元字符及其作用:
元字符 | 功能描述 | 示例 |
---|---|---|
. |
匹配除换行符之外的任意单个字符 | a.c 能匹配 abc 、adc |
^ |
匹配字符串的起始位置 | ^hello 可匹配 hello world |
$ |
匹配字符串的结束位置 | world$ 能匹配 hello world |
* |
匹配前面的字符0次或者多次 | ab* 可以匹配 a 、ab 、abb |
+ |
匹配前面的字符1次或者多次 | ab+ 能匹配 ab 、abb ,但不能匹配 a |
? |
匹配前面的字符0次或者1次 | ab? 可以匹配 a 、ab |
{n} |
匹配前面的字符恰好n次 | a{3} 能匹配 aaa |
{n,} |
匹配前面的字符至少n次 | a{2,} 可以匹配 aa 、aaa |
{n,m} |
匹配前面的字符至少n次,最多m次 | a{2,3} 能匹配 aa 、aaa |
[] |
匹配方括号中指定的任意一个字符 | [abc] 可以匹配 a 、b 或者 c |
[^] |
匹配不在方括号中的任意一个字符 | [^abc] 能匹配除 a 、b 、c 之外的字符 |
\| |
匹配两个或多个模式中的任意一个 | a\|b 可以匹配 a 或者 b |
() |
对模式进行分组,并且可以捕获匹配的内容 | (ab)+ 能匹配 ab 、abab |
2. 常用的字符类
字符类是用于简化常见字符集合的表示方式:
字符类 | 等价表示 | 匹配情况 |
---|---|---|
\d |
[0-9] |
匹配任意一个数字字符 |
\D |
[^0-9] |
匹配任意一个非数字字符 |
\w |
[a-zA-Z0-9_] |
匹配任意一个字母、数字或下划线字符 |
\W |
[^a-zA-Z0-9_] |
匹配任意一个非字母、数字和下划线的字符 |
\s |
[ \t\n\r\f\v] |
匹配任意一个空白字符(包括空格、制表符、换行符等) |
\S |
[^ \t\n\r\f\v] |
匹配任意一个非空白字符 |
3. Python中的re模块
Python通过re
模块来支持正则表达式操作,下面是一些核心函数:
3.1 re.match()
从字符串的起始位置开始进行匹配,如果起始位置匹配成功,就返回匹配对象,否则返回None
。
import re
pattern = r'hello'
text = 'hello world'
match = re.match(pattern, text)
if match:
print('匹配成功:', match.group()) # 输出: 匹配成功: hello
else:
print('匹配失败')
3.2 re.search()
在整个字符串中进行搜索匹配,找到第一个匹配项后就返回匹配对象,否则返回None
。
pattern = r'world'
text = 'hello world'
search = re.search(pattern, text)
if search:
print('找到匹配:', search.group()) # 输出: 找到匹配: world
3.3 re.findall()
在字符串中查找所有符合模式的子串,并以列表的形式返回。
pattern = r'\d+' # 匹配一个或多个数字
text = '我今年25岁,身高175厘米'
numbers = re.findall(pattern, text)
print('找到的数字:', numbers) # 输出: 找到的数字: ['25', '175']
3.4 re.sub()
对字符串中符合模式的子串进行替换。
pattern = r'apple'
text = 'I like apple'
new_text = re.sub(pattern, 'banana', text)
print('替换后的文本:', new_text) # 输出: 替换后的文本: I like banana
3.5 re.split()
根据匹配模式对字符串进行分割,并以列表的形式返回分割后的结果。
pattern = r'\s+' # 匹配一个或多个空白字符
text = 'hello world'
words = re.split(pattern, text)
print('分割后的单词:', words) # 输出: 分割后的单词: ['hello', 'world']
4. 匹配对象的方法
当使用match()
、search()
等函数成功匹配后,会返回一个匹配对象,该对象有以下常用方法:
方法 | 功能描述 |
---|---|
group() |
返回匹配的子串 |
groups() |
返回所有捕获组的元组 |
start() |
返回匹配开始的位置 |
end() |
返回匹配结束的位置 |
span() |
返回一个包含匹配开始和结束位置的元组 |
下面是一个实例:
pattern = r'(\d{3})-(\d{4})' # 匹配如 123-4567 这样的模式
text = '电话号码: 123-4567'
match = re.search(pattern, text)
if match:
print('完整匹配:', match.group()) # 输出: 完整匹配: 123-4567
print('第一组:', match.group(1)) # 输出: 第一组: 123
print('第二组:', match.group(2)) # 输出: 第二组: 4567
print('所有组:', match.groups()) # 输出: 所有组: ('123', '4567')
print('匹配位置:', match.span()) # 输出: 匹配位置: (5, 13)
5. 贪婪匹配与非贪婪匹配
正则表达式默认采用贪婪匹配,也就是尽可能多地匹配字符。在量词后面加上?
,可以将贪婪匹配转换为非贪婪匹配,即尽可能少地匹配字符。
贪婪匹配示例:
text = '<html><body><h1>标题</h1></body></html>'
pattern = r'<.*>' # 贪婪匹配
result = re.findall(pattern, text)
print('贪婪匹配结果:', result) # 输出: ['<html><body><h1>标题</h1></body></html>']
非贪婪匹配示例:
pattern = r'<.*?>' # 非贪婪匹配
result = re.findall(pattern, text)
print('非贪婪匹配结果:', result) # 输出: ['<html>', '<body>', '<h1>', '</h1>', '</body>', '</html>']
6. 标志位
在使用正则表达式时,可以通过标志位来修改匹配的行为,常见的标志位如下:
标志位 | 功能描述 |
---|---|
re.I |
忽略大小写进行匹配 |
re.M |
多行匹配模式 |
re.S |
让. 可以匹配包括换行符在内的任意字符 |
下面是实例:
text = 'Hello World\nHELLO PYTHON'
pattern = r'hello'
# 忽略大小写匹配
matches = re.findall(pattern, text, re.I)
print('忽略大小写匹配结果:', matches) # 输出: ['Hello', 'HELLO']
# 多行匹配模式
pattern = r'^HELLO'
matches = re.findall(pattern, text, re.I | re.M)
print('多行匹配结果:', matches) # 输出: ['Hello', 'HELLO']
7. 实例应用
7.1 验证邮箱格式
def validate_email(email):
pattern = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
return re.match(pattern, email) is not None
print(validate_email('test@example.com')) # 输出: True
print(validate_email('invalid.email@.com')) # 输出: False
7.2 提取URL中的域名
url = 'https://www.example.com/path?query=test'
pattern = r'https?://([^/?#]+)'
match = re.search(pattern, url)
if match:
print('域名:', match.group(1)) # 输出: 域名: www.example.com
8. 注意事项
- 转义字符:在正则表达式中使用特殊字符(如
\
、.
、*
)时,需要进行转义或者使用原始字符串(r''
)。 - 性能考量:复杂的正则表达式可能会影响性能,在处理大量文本时要格外注意。
- 调试工具:可以借助regex101等工具来调试正则表达式。
通过上述内容,你已经对Python正则表达式有了全面的了解。正则表达式的核心在于多练习,通过不断实践来掌握各种元字符和模式的运用。
评论区
暂无评论,快来发表第一条评论吧~