Python中re对象的使用方法

re模块是Python中用于正则表达式操作的标准库模块。正则表达式(Regular Expression)是一种强大的文本处理工具,可以用来匹配、查找、替换字符串中的特定模式。

1. re模块的基本方法

1.1 re.compile()

将正则表达式模式编译成一个正则表达式对象,可以重复使用。

python 复制代码
import re

pattern = re.compile(r'\d+')  # 匹配一个或多个数字

1.2 re.match()

从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功则返回None。

python 复制代码
result = re.match(r'hello', 'hello world')
if result:
    print("匹配成功:", result.group())  # 输出: 匹配成功: hello

1.3 re.search()

扫描整个字符串并返回第一个成功的匹配。

python 复制代码
result = re.search(r'world', 'hello world')
if result:
    print("找到匹配:", result.group())  # 输出: 找到匹配: world

1.4 re.findall()

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表。

python 复制代码
numbers = re.findall(r'\d+', '12 apples, 34 oranges, 56 bananas')
print(numbers)  # 输出: ['12', '34', '56']

1.5 re.finditer()

与findall类似,但返回一个迭代器,包含所有匹配的Match对象。

python 复制代码
matches = re.finditer(r'\d+', '12 apples, 34 oranges, 56 bananas')
for match in matches:
    print(match.group(), match.span())

1.6 re.sub()

用于替换字符串中的匹配项。

python 复制代码
text = re.sub(r'\d+', 'NUM', '12 apples, 34 oranges, 56 bananas')
print(text)  # 输出: NUM apples, NUM oranges, NUM bananas

1.7 re.split()

按照能够匹配的子串将字符串分割后返回列表。

python 复制代码
words = re.split(r'\W+', 'Hello, world! This is a test.')
print(words)  # 输出: ['Hello', 'world', 'This', 'is', 'a', 'test', '']

2. 正则表达式对象的方法

编译后的正则表达式对象也有相应的方法:

python 复制代码
pattern = re.compile(r'\d+')

# 对应的方法
pattern.match(string)      # 同re.match()
pattern.search(string)     # 同re.search()
pattern.findall(string)    # 同re.findall()
pattern.finditer(string)   # 同re.finditer()
pattern.sub(repl, string)  # 同re.sub()
pattern.split(string)      # 同re.split()

3. Match对象的方法和属性

匹配成功后返回的Match对象有以下常用方法和属性:

3.1 方法

  • group([group1, ...]): 返回一个或多个匹配的子组
  • groups(): 返回一个包含所有匹配子组的元组
  • groupdict(): 返回一个包含所有命名子组的字典
  • start([group]): 返回匹配子组的起始位置
  • end([group]): 返回匹配子组的结束位置
  • span([group]): 返回一个元组包含匹配子组的(start, end)位置

3.2 属性

  • pos: 搜索开始的位置
  • endpos: 搜索结束的位置
  • lastindex: 最后一个匹配的捕获组的索引
  • lastgroup: 最后一个匹配的捕获组的名称
  • re: 产生此匹配的正则表达式对象
  • string: 匹配的字符串

4. 正则表达式模式语法

4.1 常用元字符

  • .: 匹配任意字符(除了换行符)
  • ^: 匹配字符串的开头
  • $: 匹配字符串的结尾
  • *: 匹配前面的子表达式零次或多次
  • +: 匹配前面的子表达式一次或多次
  • ?: 匹配前面的子表达式零次或一次
  • {m}: 匹配前面的子表达式m次
  • {m,n}: 匹配前面的子表达式m到n次
  • [...]: 字符集,匹配其中任意一个字符
  • |: 或,匹配|左右任意一个表达式
  • (...): 分组,标记一个子表达式的开始和结束位置

4.2 特殊序列

  • \d: 匹配任意数字,等价于[0-9]
  • \D: 匹配任意非数字字符
  • \s: 匹配任意空白字符
  • \S: 匹配任意非空白字符
  • \w: 匹配任意字母数字字符,等价于[a-zA-Z0-9_]
  • \W: 匹配任意非字母数字字符
  • \b: 匹配单词边界
  • \B: 匹配非单词边界

5. 高级用法

5.1 分组和捕获

python 复制代码
pattern = re.compile(r'(\d{3})-(\d{3})-(\d{4})')  # 电话号码格式
match = pattern.search('我的电话是123-456-7890')
if match:
    print("完整匹配:", match.group(0))  # 123-456-7890
    print("区号:", match.group(1))     # 123
    print("前三位:", match.group(2))   # 456
    print("后四位:", match.group(3))   # 7890
    print("所有分组:", match.groups()) # ('123', '456', '7890')

5.2 非捕获组

(?:...)表示非捕获组,匹配但不捕获

python 复制代码
pattern = re.compile(r'(?:\d{3})-(\d{3})-(\d{4})')
match = pattern.search('123-456-7890')
print(match.groups())  # 输出: ('456', '7890')

5.3 命名组

(?P<name>...)可以给分组命名

python 复制代码
pattern = re.compile(r'(?P<area>\d{3})-(?P<first>\d{3})-(?P<last>\d{4})')
match = pattern.search('123-456-7890')
print(match.groupdict())  # {'area': '123', 'first': '456', 'last': '7890'}

5.4 前后查找

  • (?=...): 正向后查找
  • (?!...): 负向后查找
  • (?<=...): 正向前查找
  • (?<!...): 负向前查找
python 复制代码
# 匹配后面跟着"bar"的"foo"
re.findall(r'foo(?=bar)', 'foobar foobaz')  # ['foo']

# 匹配后面不跟着"bar"的"foo"
re.findall(r'foo(?!bar)', 'foobar foobaz')  # ['foo']

# 匹配前面是"foo"的"bar"
re.findall(r'(?<=foo)bar', 'foobar bazbar')  # ['bar']

# 匹配前面不是"foo"的"bar"
re.findall(r'(?<!foo)bar', 'foobar bazbar')  # ['bar']

6. 标志参数

re模块支持多个标志参数,可以修改正则表达式的行为:

  • re.IGNORECASEre.I: 忽略大小写
  • re.MULTILINEre.M: 多行模式
  • re.DOTALLre.S: 使.匹配包括换行符在内的所有字符
  • re.VERBOSEre.X: 允许编写更易读的正则表达式
  • re.ASCIIre.A: 使\w, \W, \b, \B, \s, \S只匹配ASCII字符
  • re.DEBUG: 显示调试信息
python 复制代码
# 忽略大小写
re.findall(r'hello', 'Hello World', re.I)  # ['Hello']

# 多行模式
text = """first line
second line
third line"""
re.findall(r'^\w+', text, re.M)  # ['first', 'second', 'third']

# 详细模式,可以添加注释和空白
pattern = re.compile(r"""
    \d{3}   # 区号
    -       # 分隔符
    \d{3}   # 前三位
    -       # 分隔符
    \d{4}   # 后四位
""", re.VERBOSE)

7. 实际应用示例

7.1 验证电子邮件地址

python 复制代码
def is_valid_email(email):
    pattern = re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$')
    return bool(pattern.match(email))

print(is_valid_email('user@example.com'))  # True
print(is_valid_email('invalid.email@'))    # False

7.2 提取URL

python 复制代码
text = "访问我的网站 https://www.example.com 或者 http://test.org"
urls = re.findall(r'https?://[^\s]+', text)
print(urls)  # ['https://www.example.com', 'http://test.org']

7.3 替换日期格式

python 复制代码
text = "今天是2023-05-15,明天是2023-05-16"
new_text = re.sub(r'(\d{4})-(\d{2})-(\d{2})', r'\2/\3/\1', text)
print(new_text)  # 今天是05/15/2023,明天是05/16/2023

7.4 密码强度验证

python 复制代码
def check_password_strength(password):
    if len(password) < 8:
        return "密码太短"
    if not re.search(r'[A-Z]', password):
        return "需要至少一个大写字母"
    if not re.search(r'[a-z]', password):
        return "需要至少一个小写字母"
    if not re.search(r'\d', password):
        return "需要至少一个数字"
    if not re.search(r'[^A-Za-z0-9]', password):
        return "需要至少一个特殊字符"
    return "密码强度足够"

print(check_password_strength('Weak123'))  # 密码太短
print(check_password_strength('Strong@Password123'))  # 密码强度足够

8. 性能考虑

  1. 预编译正则表达式 :如果需要多次使用同一个正则表达式,使用re.compile()预编译可以提高性能。
  2. 避免贪婪匹配 :贪婪匹配(如.*)可能会导致性能问题,尽量使用非贪婪匹配(如.*?)或更具体的模式。
  3. 使用原子组(?>...)可以防止回溯,提高性能。
  4. 避免过度使用捕获组 :只捕获需要的内容,使用非捕获组(?:...)减少开销。
python 复制代码
# 预编译示例
pattern = re.compile(r'\d+')  # 编译一次
for text in large_text_collection:
    matches = pattern.findall(text)  # 多次使用

正则表达式是一个强大的工具,但也可能变得复杂难以维护。对于特别复杂的模式,考虑将其分解为多个简单的正则表达式,或者编写专门的解析器。

相关推荐
之歆17 分钟前
Python-TCP编程-UDP编程-SocketServer-IO各种概念及多路复用-asyncio-学习笔记
python·tcp/ip·udp
UrbanJazzerati1 小时前
Python 编程基础:掌握缩进、多行语句与引号
python
羊八井1 小时前
使用 Playwright 构建小红书笔记采集:从架构设计到实战应用
爬虫·python
听风者6771 小时前
python虚拟环境搭建本地cmd+pycharm配置
python
做科研的周师兄1 小时前
PyCharm 高效入门指南:从安装到进阶,解锁 Python 开发全流程
ide·python·pycharm
秋水丶秋水1 小时前
Python常见异常和处理方案
后端·python
LuckyLay2 小时前
1.2.2 高级特性详解——AI教你学Django
python·django·sqlite
【本人】2 小时前
Django基础(三)———模板
后端·python·django
varphp2 小时前
宝塔申请证书错误,提示 module ‘OpenSSL.crypto‘ has no attribute ‘sign‘
服务器·python·宝塔
电饭叔3 小时前
《python语言程序设计》2018版第8章8题编写函数实现二进制转十进制(字符串变整数)!!整数没法进行下标
开发语言·python