正则表达式的艺术:轻松驾驭 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 [email protected]. You can also reach me at [email protected].
'''
 
pattern = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
emails = re.findall(pattern, text)
print(emails)  # 输出: ['[email protected]', '[email protected]']

案例二:解析 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)。

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

六、总结

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

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

相关推荐
Leo.yuan5 分钟前
数据库同步是什么意思?数据库架构有哪些?
大数据·数据库·oracle·数据分析·数据库架构
zhangzhangkeji6 分钟前
(33)课54--??:3 张表的 join-on 连接举例,多表查询总结。
mysql
风铃儿~6 分钟前
Spring AI 入门:Java 开发者的生成式 AI 实践之路
java·人工智能·spring
Kookoos11 分钟前
ABP VNext 与 Neo4j:构建基于图数据库的高效关系查询
数据库·c#·.net·neo4j·abp vnext
斯普信专业组11 分钟前
Tomcat全方位监控实施方案指南
java·tomcat
忆雾屿22 分钟前
云原生时代 Kafka 深度实践:06原理剖析与源码解读
java·后端·云原生·kafka
武昌库里写JAVA35 分钟前
iview Switch Tabs TabPane 使用提示Maximum call stack size exceeded堆栈溢出
java·开发语言·spring boot·学习·课程设计
云之兕37 分钟前
MyBatis 的动态 SQL
数据库·sql·mybatis
gaoliheng00643 分钟前
Redis看门狗机制
java·数据库·redis
我是唐青枫1 小时前
.NET AOT 详解
java·服务器·.net