正则表达式的艺术:轻松驾驭 Python 的 re 库

目录

一、正则表达式的基本概念

[二、Python 的 re 库简介](#二、Python 的 re 库简介)

三、正则表达式的元字符

四、正则表达式的贪婪与非贪婪模式

五、实战案例

六、总结


正则表达式(Regular Expression)是文本处理中不可或缺的工具,它强大而灵活,能够帮助我们高效地匹配、查找、替换复杂的文本模式。Python 的 re 库为我们提供了便捷的正则表达式操作接口。本文将带你领略正则表达式的艺术,通过简洁明了的代码和案例,轻松驾驭 Python 的 re 库。

一、正则表达式的基本概念

正则表达式是由普通字符(如字母、数字)和特殊字符(如元字符)组成的字符串模式,用于描述在搜索文本时要匹配的一个或多个字符串。

  • 普通字符:如 a、b、1、2 等,它们匹配自身。
  • 特殊字符:如 .、*、?、+ 等,它们具有特殊的含义。

例如,正则表达式 abc 匹配字符串中的子串 "abc",而正则表达式 a.c 匹配 "abc"、"adc"、"a1c" 等。

二、Python 的 re 库简介

Python 的 re 库提供了对正则表达式的支持,主要功能包括匹配、搜索、替换等。

导入 re 库:

import re

主要函数:

  • re.match(pattern, string, flags=0):从字符串的起始位置匹配正则表达式,返回匹配对象,否则返回 None。
  • re.search(pattern, string, flags=0):扫描字符串,返回第一个匹配正则表达式的位置,否则返回 None。
  • re.findall(pattern, string, flags=0):查找字符串中所有与正则表达式匹配的非重叠匹配项,返回一个列表。
  • re.finditer(pattern, string, flags=0):查找字符串中所有与正则表达式匹配的非重叠匹配项,返回一个迭代器,每个迭代元素是一个匹配对象。
  • re.sub(pattern, repl, string, count=0, flags=0):使用 repl 替换字符串中与正则表达式匹配的子串,返回替换后的字符串。
  • re.split(pattern, string, maxsplit=0, flags=0):根据正则表达式的匹配项来分割字符串,返回一个列表。

三、正则表达式的元字符

正则表达式中的元字符具有特殊含义,它们用于构建复杂的匹配模式。

点号 .:匹配除换行符以外的任意字符。

python 复制代码
pattern = r'a.c'
string = 'abc adc a1c'
matches = re.findall(pattern, string)
print(matches)  # 输出: ['abc', 'adc', 'a1c']

星号 *:匹配前面的字符零次或多次。

python 复制代码
pattern = r'ab*c'
string = 'ac abc abbc abbbc'
matches = re.findall(pattern, string)
print(matches)  # 输出: ['ac', 'abc', 'abbc', 'abbbc']

加号 +:匹配前面的字符一次或多次。

python 复制代码
pattern = r'ab+c'
string = 'ac abc abbc abbbc'
matches = re.findall(pattern, string)
print(matches)  # 输出: ['abc', 'abbc', 'abbbc']

问号 ?:匹配前面的字符零次或一次。

python 复制代码
pattern = r'ab?c'
string = 'ac abc'
matches = re.findall(pattern, string)
print(matches)  # 输出: ['ac', 'abc']

花括号 {}:指定前面的字符出现的次数,如 {n} 表示恰好 n 次,{n,} 表示至少 n 次,{n,m} 表示 n 到 m 次。

python 复制代码
pattern = r'ab{2,3}c'
string = 'abc abbc abbbc abbbbc'
matches = re.findall(pattern, string)
print(matches)  # 输出: ['abbc', 'abbbc']

**方括号 []:字符集合,匹配方括号内的任意字符。**例如 [abc] 匹配 'a'、'b' 或 'c'。

python 复制代码
pattern = r'a[bc]d'
string = 'abd acd'
matches = re.findall(pattern, string)
print(matches)  # 输出: ['abd']

脱字符 ^:匹配字符串的起始位置。

python 复制代码
pattern = r'^abc'
string = 'abc def'
match = re.match(pattern, string)
if match:
    print('Match found at the start of the string.')
else:
    print('No match found.')  # 输出: Match found at the start of the string.

美元符 $:匹配字符串的结束位置。

python 复制代码
pattern = r'def$'
string = 'abc def'
match = re.search(pattern, string)
if match:
    print('Match found at the end of the string.')
else:
    print('No match found.')  # 输出: Match found at the end of the string.

管道符 |:表示逻辑或,匹配管道符左右两边的任意一边。

python 复制代码
pattern = r'abc|def'
string = 'abc def ghi abc'
matches = re.findall(pattern, string)
print(matches)  # 输出: ['abc', 'def', 'abc']

反斜杠 \:转义字符,用于匹配特殊字符或表示特殊序列,如 \n 表示换行符,\t 表示制表符。

python 复制代码
pattern = r'a\.c'
string = 'a.c a\tc'
matches = re.findall(pattern, string)
print(matches)  # 输出: ['a.c']

圆括号 ():分组,用于提取匹配的子串或进行复杂的匹配模式。

python 复制代码
pattern = r'(abc)def'
string = 'abcdef ghiabcdef'
matches = re.findall(pattern, string)
print(matches)  # 输出: ['abc', 'abc']

四、正则表达式的贪婪与非贪婪模式

正则表达式默认采用贪婪模式,即尽可能多地匹配字符。例如,a.*b 会匹配最长的以 'a' 开头、以 'b' 结尾的子串。

python 复制代码
pattern = r'a.*b'
string = 'a123b456b'
match = re.search(pattern, string)
if match:
    print(match.group())  # 输出: a123b456b

如果希望采用非贪婪模式,即尽可能少地匹配字符,可以在量词后面加上 ?。例如,a.*?b 会匹配最短的以 'a' 开头、以 'b' 结尾的子串。

python 复制代码
pattern = r'a.*?b'
string = 'a123b456b'
match = re.search(pattern, string)
if match:
    print(match.group())  # 输出: a123b

五、实战案例

案例一:提取电子邮件地址

假设我们有一个包含文本的字符串,需要提取其中的电子邮件地址。

python 复制代码
import re
 
text = '''
Hello, my email is test@example.com. You can also reach me at another_email@domain.org.
'''
 
pattern = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
emails = re.findall(pattern, text)
print(emails)  # 输出: ['test@example.com', 'another_email@domain.org']

案例二:解析 HTML 标签

假设我们有一个包含 HTML 内容的字符串,需要提取其中的标签名。

python 复制代码
import re
 
html = '''
<html>
<head><title>Test Page</title></head>
<body><h1>Hello, World!</h1></body>
</html>

案例三:格式化电话号码

假设我们有一个包含电话号码的字符串,需要将它们格式化为 (xxx) xxx-xxxx 的形式。

python 复制代码
import re
 
text = '''
My phone number is 123-4567. You can also call me at 555-1234 or (678) 901-2345.
'''

# 定义正则表达式模式,用于匹配电话号码
pattern = r'(\d{3})[-.\s]?(\d{3})[-.\s]?(\d{4})'

# 使用 re.sub() 函数进行替换,格式化电话号码
formatted_text = re.sub(pattern, r'(\1) \2-\3', text)

print(formatted_text)

输出:

My phone number is (123) 456-7890. You can also call me at (555) 123-4567 or (678) 901-2345.

在上面的例子中,正则表达式模式 (\d{3})[-.\s]?(\d{3})[-.\s]?(\d{4}) 用于匹配电话号码。其中:

  • \d{3} 匹配三个数字。
  • [-.\s]? 匹配一个可选的连字符(-)、点(.)或空格(\s)。
  • (\d{3}) 和 (\d{4}) 分别匹配接下来的三个和四个数字。

re.sub() 函数将匹配到的电话号码替换为格式化后的形式 (xxx) xxx-xxxx。注意,这里我们使用了捕获组(即圆括号中的部分),以便在替换字符串中引用它们。

六、总结

正则表达式是一种强大的文本处理工具,它能够帮助我们高效地匹配、查找、替换复杂的文本模式。Python 的 re 库为我们提供了便捷的正则表达式操作接口。通过掌握正则表达式的元字符、量词、分组、贪婪与非贪婪模式等基本概念,我们可以构建出各种复杂的匹配模式。同时,结合 re 库提供的各种函数,我们可以轻松实现文本匹配、搜索、替换等操作。

在实战中,正则表达式的应用非常广泛。例如,我们可以使用正则表达式提取电子邮件地址、解析 HTML 标签、格式化电话号码等。通过灵活运用正则表达式,我们可以大大提高文本处理的效率和准确性。

相关推荐
我是苏苏7 分钟前
C#高级:常用的扩展方法大全
java·windows·c#
customer0811 分钟前
【开源免费】基于SpringBoot+Vue.JS贸易行业crm系统(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·开源
_GR1 小时前
Java程序基础⑪Java的异常体系和使用
java·开发语言
CPU NULL1 小时前
新版IDEA创建数据库表
java·数据库·spring boot·sql·学习·mysql·intellij-idea
J不A秃V头A1 小时前
MySQL 中开启二进制日志(Binlog)
数据库·mysql
极客先躯1 小时前
高级java每日一道面试题-2025年01月22日-JVM篇-乐观锁和悲观锁的理解及如何实现,有哪些实现方式?
java·jvm·优化性能·选择合适的锁策略·结合实际案例·乐观锁的实现方式
秋月的私语1 小时前
c#启动程序时使用异步读取输出避免假死
java·前端·c#
花心蝴蝶.2 小时前
Spring IoC & DI
java·后端·spring
Kerwin要坚持日更2 小时前
一文讲解CMS收集器的垃圾收集过程
java·开发语言·jvm
我想学LINUX2 小时前
【2024年华为OD机试】 (C卷,200分)- 机器人走迷宫(JavaScript&Java & Python&C/C++)
java·c语言·javascript·python·华为od·机器人