Feelings

无封面

2025-07-31
编辑

python正则表达式详解

在Python里,正则表达式是进行字符串模式匹配与操作的有力工具。下面将详细介绍Python正则表达式的相关知识,并且结合实例来加深理解。

1. 基础元字符

元字符是正则表达式里具有特殊含义的字符,下面是一些常用的元字符及其作用:

元字符 功能描述 示例
. 匹配除换行符之外的任意单个字符 a.c 能匹配 abcadc
^ 匹配字符串的起始位置 ^hello 可匹配 hello world
$ 匹配字符串的结束位置 world$ 能匹配 hello world
* 匹配前面的字符0次或者多次 ab* 可以匹配 aababb
+ 匹配前面的字符1次或者多次 ab+ 能匹配 ababb,但不能匹配 a
? 匹配前面的字符0次或者1次 ab? 可以匹配 aab
{n} 匹配前面的字符恰好n次 a{3} 能匹配 aaa
{n,} 匹配前面的字符至少n次 a{2,} 可以匹配 aaaaa
{n,m} 匹配前面的字符至少n次,最多m次 a{2,3} 能匹配 aaaaa
[] 匹配方括号中指定的任意一个字符 [abc] 可以匹配 ab 或者 c
[^] 匹配不在方括号中的任意一个字符 [^abc] 能匹配除 abc 之外的字符
\| 匹配两个或多个模式中的任意一个 a\|b 可以匹配 a 或者 b
() 对模式进行分组,并且可以捕获匹配的内容 (ab)+ 能匹配 ababab

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正则表达式有了全面的了解。正则表达式的核心在于多练习,通过不断实践来掌握各种元字符和模式的运用。

评论区

昵称最多15个字符,包含汉字、字母、数字等

暂无评论,快来发表第一条评论吧~