0

0

Python正则表达式怎么用?文本匹配技巧

雪夜

雪夜

发布时间:2025-08-12 12:12:02

|

419人浏览过

|

来源于php中文网

原创

python正则表达式通过re模块实现文本匹配与处理,1.常用函数包括re.search()查找首个匹配、re.match()从开头匹配、re.findall()获取所有匹配、re.sub()替换匹配内容、re.compile()预编译模式提升效率;2.核心语法涵盖通配符、量词、字符集、分组、转义等,支持复杂模式构建;3.高级技巧包括贪婪与非贪婪控制、分组捕获与非捕获、匹配标志应用如忽略大小写和多行模式;4.性能优化需预编译正则、避免灾难性回溯;5.常见陷阱涉及原始字符串缺失、match与search混淆、字符集内元字符误解;6.适用场景为模式匹配、结构化数据提取、动态替换等复杂文本处理,而简单操作优先使用字符串方法。

Python正则表达式怎么用?文本匹配技巧

Python的正则表达式,说白了,就是一套用来描述和匹配字符串模式的强大工具。它通过一套特殊的字符序列(也就是“正则模式”)来查找、替换或提取文本中符合特定规则的内容。在Python里,我们主要通过内置的

re
模块来使用它,这玩意儿在处理各种文本数据时简直是利器。

Python正则表达式怎么用?文本匹配技巧

解决方案

要用好Python的正则表达式,核心在于理解

re
模块提供的几个关键函数和基本的正则语法。

首先,你需要导入

re
模块:
import re

立即学习Python免费学习笔记(深入)”;

Python正则表达式怎么用?文本匹配技巧

最常用的几个函数:

  • re.search(pattern, string, flags=0)
    : 这个函数会在整个字符串中查找第一个匹配
    pattern
    的位置。如果找到,返回一个匹配对象(Match object),否则返回
    None
    。它只会返回第一个匹配结果,如果你想找所有的,就得循环或者用
    findall

    Python正则表达式怎么用?文本匹配技巧
    text = "我的电话是138-0000-1234,工作电话是010-87654321。"
    # 查找手机号
    match = re.search(r'\d{3}-\d{4}-\d{4}', text)
    if match:
        print(f"找到手机号: {match.group()}") # 输出:找到手机号: 138-0000-1234
  • re.match(pattern, string, flags=0)
    : 和
    search
    类似,但
    match
    只从字符串的开头进行匹配。如果模式不在字符串的起始位置,它就找不到。

    text1 = "Hello World"
    text2 = "World Hello"
    print(re.match(r'Hello', text1)) # <re.Match object; span=(0, 5), match='Hello'>
    print(re.match(r'Hello', text2)) # None
  • re.findall(pattern, string, flags=0)
    : 这个函数会找到字符串中所有不重叠的
    pattern
    匹配,并以列表的形式返回所有匹配的字符串。

    text = "电子邮件地址有:test@example.com 和 info@domain.org。"
    emails = re.findall(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', text)
    print(f"找到的邮箱: {emails}")
    # 输出:找到的邮箱: ['test@example.com', 'info@domain.org']
  • re.sub(pattern, repl, string, count=0, flags=0)
    : 替换字符串中所有匹配
    pattern
    的部分为
    repl
    count
    参数可以限制替换的次数。

    text = "我喜欢苹果,也喜欢香蕉,还喜欢苹果。"
    new_text = re.sub(r'苹果', '橘子', text)
    print(f"替换后: {new_text}") # 输出:替换后: 我喜欢橘子,也喜欢香蕉,还喜欢橘子。
  • re.compile(pattern, flags=0)
    : 当你需要多次使用同一个正则表达式模式时,用
    re.compile()
    预编译它会更高效。它返回一个正则表达式对象,然后你可以在这个对象上调用
    search
    findall
    等方法。

    phone_pattern = re.compile(r'\d{3}-\d{4}-\d{4}')
    text1 = "我的电话是138-0000-1234。"
    text2 = "联系方式是139-1111-2222。"
    print(phone_pattern.search(text1).group())
    print(phone_pattern.search(text2).group())

一些常用的正则语法元素:

  • .
    : 匹配除换行符以外的任意字符。
  • *``**: 匹配前一个字符零次或多次。
  • +
    : 匹配前一个字符一次或多次。
  • ?
    : 匹配前一个字符零次或一次(也用于非贪婪匹配)。
  • []
    : 字符集,匹配方括号内的任意一个字符。例如
    [abc]
    匹配 'a', 'b', 或 'c'。
    [0-9]
    匹配任意数字。
  • ()
    : 分组,可以用来捕获匹配的内容,或者对多个字符应用量词。
  • |
    : 或,匹配左右两边的任意一个模式。例如
    cat|dog
    匹配 'cat' 或 'dog'。
  • ^
    : 匹配字符串的开始。
  • $
    : 匹配字符串的结束。
  • \
    : 转义字符,用于匹配特殊字符本身,例如
    \.
    匹配点号。
  • \d
    : 匹配任意数字(等同于
    [0-9]
    )。
  • \w
    : 匹配字母、数字或下划线(等同于
    [A-Za-z0-9_]
    )。
  • \s
    : 匹配任意空白字符(空格、制表符、换行符等)。
  • \b
    : 匹配单词边界。

记住,在Python中使用正则表达式时,最好使用原始字符串(raw string),即在字符串前加

r
,例如
r'\d+'
。这样可以避免反斜杠被Python解释器误认为是转义字符,导致不必要的麻烦。

Python正则表达式在处理文本数据时有哪些高级应用技巧?

说实话,高级技巧这东西,很多时候就是把基础元素玩出花来。我个人觉得,真正能提升你正则功力的,除了熟练运用基本语法,就是理解一些更微妙的概念和功能了。

一个很有用的概念是贪婪与非贪婪匹配。默认情况下,量词(如

*
,
+
,
?
,
{m,n}
)都是“贪婪”的,它们会尽可能多地匹配字符。但有时候我们希望它尽可能少地匹配,这时就可以在量词后面加上一个问号
?
,使其变为“非贪婪”模式。

比如,你想从

<p>这是一个段落</p><p>这是另一个段落</p>
中只提取第一个
<p>...</p>
。 如果用
r'<p>.*</p>'
,它会匹配到
这是一个段落</p><p>这是另一个段落</p>
,因为
.*
会一直匹配到最后一个
</p>
。 但如果用
r'<p>.*?</p>'
.*?
就会非贪婪地匹配到第一个
</p>
处,这样就能正确地提取出
这是一个段落</p>
。这个小小的
?
真是解决了不少头疼的问题。

另一个我觉得挺实用的是分组与捕获。用括号

()
创建的分组,不仅可以对一部分模式应用量词,还能捕获匹配到的内容。你可以通过匹配对象的
group(index)
方法来获取这些捕获到的子字符串。 比如,从日期字符串 "2023-10-26" 中分别提取年、月、日:

date_str = "2023-10-26"
match = re.search(r'(\d{4})-(\d{2})-(\d{2})', date_str)
if match:
    year = match.group(1) # 2023
    month = match.group(2) # 10
    day = match.group(3) # 26
    print(f"年: {year}, 月: {month}, 日: {day}")

有时候你只想分组,但不想捕获内容,可以使用非捕获分组

(?:...)
。这在构建复杂模式时很有用,可以避免创建不必要的捕获组,提升一点点性能,主要是让你的匹配对象更干净。

还有就是正则表达式的标志(Flags)

re
模块提供了一些标志,可以改变匹配的行为。比如:

  • re.IGNORECASE
    re.I
    : 忽略大小写。
  • re.MULTILINE
    re.M
    : 让
    ^
    $
    不仅匹配字符串的开始/结束,还匹配每一行的开始/结束(在多行模式下)。
  • re.DOTALL
    re.S
    : 让
    .
    匹配包括换行符在内的所有字符。这在处理跨越多行的文本块时特别有用。
text_multiline = "第一行\n第二行"
# 默认情况下,. 不匹配换行符
print(re.search(r'.+', text_multiline).group()) # 第一行
# 使用 re.DOTALL,. 匹配换行符
print(re.search(r'.+', text_multiline, re.DOTALL).group()) # 第一行\n第二行

这些高级应用,其实就是对基本概念的灵活组合和对细节的把握。我发现很多人一开始会觉得这些概念有点绕,但一旦理解了,文本处理能力会提升一大截,能解决很多以前觉得无从下手的问题。

GentleAI
GentleAI

GentleAI是一个高效的AI工作平台,为普通人提供智能计算、简单易用的界面和专业技术支持。让人工智能服务每一个人。

下载

Python正则表达式性能优化与常见陷阱有哪些?

谈到性能和陷阱,这真是个老生常谈但又不得不提的话题。我记得有一次,一个简单的正则就让程序卡死了好几秒,后来才发现是贪婪匹配惹的祸。

性能优化方面:

一个很重要的点是预编译正则表达式。如果你需要在一个程序中多次使用同一个正则表达式模式,强烈建议使用

re.compile()

# 不推荐,每次调用都会重新编译
for _ in range(10000):
    re.search(r'\d+', 'abc123def')

# 推荐,只编译一次
compiled_pattern = re.compile(r'\d+')
for _ in range(10000):
    compiled_pattern.search('abc123def')

虽然对于简单的模式和少量操作,差异不明显,但在处理大量文本或复杂模式时,性能提升是显而易见的。

另一个需要注意的,是避免“灾难性回溯”(Catastrophic Backtracking)。这通常发生在模式中包含嵌套的量词,并且这些量词可以匹配空字符串或者重叠匹配时。比如

(a+)+
或者
(a|aa)+
这样的模式。当输入字符串不匹配时,正则表达式引擎会尝试所有可能的匹配路径,导致指数级的回溯,从而使程序变得非常慢,甚至看起来像死机了一样。 解决办法通常是:

  • 使用非贪婪匹配 (
    *?
    ,
    +?
    )。
  • 优化模式,使其更精确,减少不必要的重复匹配。
  • 避免过度嵌套的重复组
  • 如果可能,考虑使用更简单的字符串方法或者分步匹配

常见陷阱:

  1. 忘记使用原始字符串(Raw Strings):前面提过,

    r''
    可以避免反斜杠的转义问题。如果你写
    '\n'
    ,Python会把它解释成换行符,而不是匹配字母 'n' 的字面量。写成
    r'\n'
    才是匹配反斜杠和字母 'n'。这个小细节经常让人犯错。

  2. re.match()
    re.search()
    的混淆
    :我见过不少人,明明想在整个字符串中查找,却误用了
    re.match()
    ,结果发现总是返回
    None
    。记住,
    match
    只看开头,
    search
    才是全局扫描。

  3. 贪婪与非贪婪的误解:这绝对是初学者最常踩的坑。我上面已经详细解释了,这里就不再赘述了。但记住,当你发现匹配结果比你预期的长时,多半就是贪婪匹配在作祟。

  4. 字符集

    []
    内的特殊字符:在
    []
    内部,很多元字符(如
    .
    ,
    *
    ,
    +
    ,
    ?
    ,
    |
    ,
    (
    ,
    )
    ,
    {
    ,
    ^
    ,
    $
    )会失去它们的特殊含义,被当作普通字符处理。但
    \
    ]
    仍然需要转义(除非
    ]
    是第一个字符)。例如,要匹配
    [foo]
    ,你得写
    r'\[foo\]'
    。而
    [.
    匹配的是字面量点号。

  5. 编码问题:当处理非ASCII字符(比如中文)时,确保你的字符串和正则表达式模式的编码是一致的。Python 3 默认处理Unicode字符串,通常问题不大,但如果你从文件读取数据,或者涉及到不同编码的系统交互,就得注意了。

总的来说,写正则就像写代码,需要测试和调试。当结果不符预期时,不要急着改代码,先仔细检查你的正则表达式,甚至可以利用在线的正则测试工具来逐步调试。

Python中什么时候该用正则表达式,什么时候用普通的字符串方法?

这是一个非常实用的问题,我个人在实际工作中也经常面临这样的选择。我的经验是,如果一个任务能用简单的字符串方法解决,就尽量不用正则。 正则虽然强大,但它的可读性确实比普通字符串方法差一些,而且写起来也更容易出错。

什么时候应该用普通的字符串方法?

  • 简单的查找和替换:如果你只是想查找一个固定的子字符串是否存在,或者用一个固定的字符串替换另一个固定的字符串,那么
    in
    运算符、
    str.find()
    ,
    str.index()
    ,
    str.replace()
    这些方法就足够了,而且它们通常更快。
    text = "Hello World"
    if "World" in text: # 简单的查找
        print("Found World")
    new_text = text.replace("World", "Python") # 简单的替换
  • 判断字符串开头或结尾
    str.startswith()
    str.endswith()
    比用
    ^
    $
    的正则表达式更直观、更高效。
    filename = "report.txt"
    if filename.endswith(".txt"):
        print("这是一个文本文件")
  • 简单的分割字符串:如果你的分隔符是固定的,
    str.split()
    是首选。
    data = "apple,banana,orange"
    fruits = data.split(',')
  • 大小写转换、去除空白等
    str.lower()
    ,
    str.upper()
    ,
    str.strip()
    等方法功能单一且高效。

什么时候应该用正则表达式?

  • 模式匹配:当你需要查找的不是一个固定的字符串,而是一种“模式”时,正则表达式是不可替代的。比如查找所有符合邮箱格式的字符串、所有电话号码、所有日期格式等。
    # 查找所有形如 "YYYY-MM-DD" 的日期
    text = "项目启动日期是2023-10-26,截止日期是2024-01-15。"
    dates = re.findall(r'\d{4}-\d{2}-\d{2}', text)
  • 复杂的字符串验证:验证用户输入是否符合特定格式(如密码强度、URL格式、身份证号等),正则表达式能提供简洁而强大的表达能力。
  • 基于模式的替换:当你需要替换的内容不是固定的,而是根据匹配到的模式来动态生成时,
    re.sub()
    结合分组捕获非常强大。
    # 将 "姓 名" 格式改为 "名 姓"
    name = "张 三"
    new_name = re.sub(r'(\S+)\s+(\S+)', r'\2 \1', name) # \1 \2 引用捕获组
    print(new_name) # 三 张
  • 从非结构化文本中提取结构化数据:比如从日志文件、网页HTML、配置文件中提取特定信息。这通常是正则表达式大显身手的地方。

很多时候,两者还会结合使用。比如,你可能先用

str.splitlines()
把一个大文本分割成行,然后对每一行使用正则表达式来提取或验证信息。

我的建议是,从最简单的方法开始考虑。如果

str
方法能解决,就用它。如果不行,或者需要处理的模式比较复杂、多变,那才是正则表达式出场的时候。熟练掌握两者的边界,能让你在文本处理时事半功倍。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

531

2023.06.20

正则表达式不包含
正则表达式不包含

正则表达式,又称规则表达式,,是一种文本模式,包括普通字符和特殊字符,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式的文本。php中文网给大家带来了有关正则表达式的相关教程以及文章,希望对大家能有所帮助。

258

2023.07.05

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

766

2023.07.05

java正则表达式匹配字符串
java正则表达式匹配字符串

在Java中,我们可以使用正则表达式来匹配字符串。本专题为大家带来java正则表达式匹配字符串的相关内容,帮助大家解决问题。

219

2023.08.11

正则表达式空格
正则表达式空格

正则表达式空格可以用“s”来表示,它是一个特殊的元字符,用于匹配任意空白字符,包括空格、制表符、换行符等。本专题为大家提供正则表达式相关的文章、下载、课程内容,供大家免费下载体验。

357

2023.08.31

Python爬虫获取数据的方法
Python爬虫获取数据的方法

Python爬虫可以通过请求库发送HTTP请求、解析库解析HTML、正则表达式提取数据,或使用数据抓取框架来获取数据。更多关于Python爬虫相关知识。详情阅读本专题下面的文章。php中文网欢迎大家前来学习。

293

2023.11.13

正则表达式空格如何表示
正则表达式空格如何表示

正则表达式空格可以用“s”来表示,它是一个特殊的元字符,用于匹配任意空白字符,包括空格、制表符、换行符等。想了解更多正则表达式空格怎么表示的内容,可以访问下面的文章。

245

2023.11.17

正则表达式中如何匹配数字
正则表达式中如何匹配数字

正则表达式中可以通过匹配单个数字、匹配多个数字、匹配固定长度的数字、匹配整数和小数、匹配负数和匹配科学计数法表示的数字的方法匹配数字。更多关于正则表达式的相关知识详情请看本专题下面的文章。php中文网欢迎大家前来学习。

547

2023.12.06

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 5万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号