文章目录

  • 使用字符串方法
  • match() VS search()
  • 贪婪 VS 非贪婪
  • 使用 `re.VERBOSE`

本篇我们将指出一些最常见的错误。

使用字符串方法

有时使用 re 模块是个错误!如果你匹配一个固定的字符串或者单个字符类,并且你没有使用 re 的任何标志(像 IGNORECASE 标志),那么就没有必要使用正则表达式了。字符串有一些方法是对固定字符串进行操作的,并且它们通常比较快。因为它们都是独立优化的 C 语言小循环,目的是在简单的情况下代替功能更加强大、更具通用性的正则表达式引擎。

举个例子,例如你想把字符串中所有的 dead 替换成 word,你会想到使用正则表达式的 re.sub() 方法来实现,但这么简单的替换,还是考虑直接使用字符串的 replace() 方法吧。但有一点你需要注意,就是 replace() 会在单词里边进行替换,像 swordfish 会变成 sdeedfish,这显然不是你想要的!replace() 没办法识别单词的边界,因此你才来考虑使用正则表达式。只需要将 RE 的模式写成 \bword\b 即可胜任此任务。

另一个常见的情况是从一个字符串中删除单个字符或者用另一个字符替代它。你也许会想到用 re.sub('\n', ' ', S) 这样的正则表达式来实现,但其实字符的 translate() 方法完全能够胜任这个任务,并且比任何正则表达式操作起来更快些

简而言之,在使用 re 模块之前,先考虑一下你的问题是否可以用更快速、简单的字符串自带方法来解决

match() VS search()

match() 函数只会检查 RE 是否在字符串的开始处匹配,而 search() 会遍历整个字符串搜索匹配的内容。记住这一区别很重要。再次强调一下,match()会报告一次成功的匹配,并且匹配的位置必须是从字符串的第一个字符开始

>>> print(re.match('super', 'superstition').span())
(0, 5)
>>> print(re.match('super', 'insuperable'))
None

另一方面,search() 函数将遍历整个字符串,并报告它找到的第一个匹配

>>> print(re.search('super', 'superstition').span())
(0, 5)
>>> print(re.search('super', 'insuperable').span())
(2, 7)

有时候你可能会耍点小聪明,使用 re.match() 然后在 RE 的前边加上 .*。但尽量不要这么做,最好采用 re.search() 代替正则表达式编译器会对 REs 做一些分析,以便可以在搜索匹配时提高速度。一般分析会先找到匹配的第一个字符是什么。举个例子,模式 Crow 必须从字符 'C' 开始匹配,那么匹配引擎分析后会快速遍历字符串,然后在 'C' 被找到之后才开始全部匹配。

按照上面的分析,你添加一个 .* 会导致这个优化失败,这就需要从头到尾扫描一遍,然后再回溯匹配 RE 剩余的部分。所以,请使用 re.search() 代替。

贪婪 VS 非贪婪

当重复一个正则表达式时,如果使用 a*,那么结果是尽可能多地去匹配。当你尝试匹配一对对称的定界符,例如 HTML 标志中的尖括号,默认的贪婪模式会使得你很困扰

我们来看下例子:

>>> s = '<html><head><title>Title</title>'
>>> len(s)
32
>>> print(re.match('<.*>', s).span())
(0, 32)
>>> print(re.match('<.*>', s).group())
<html><head><title>Title</title>

RE 匹配在 <html>< 后,.* 消耗掉字符串的剩余部分。由于正则表达式默认是贪婪的原因,RE 必须从字符串的尾部一个字符一个字符地回溯,直到找到匹配的 >。大家看到,按照这种方法,最后找到匹配内容竟是 <html> 的 < 开始,到 </title> 的 > 结束。显然这不是你想要的结果。

在这种情况下,解决方案是使用非贪婪的限定符 *?、+?、??{m,n}?,尽可能地匹配小的文本

>>> print(re.match('<.*?>', s).group())
<html>

在上边的例子中,> 在第一个 < 被匹配后立刻尝试匹配,如果失败,匹配引擎前进一步,尝试下一个字符,直到第一次匹配 >,这样就得到了我们想要的结果。

注意,使用正则表达式分析 HTML 和 XML 是很痛苦的。当你编写一个正则表达式去处理所有可能的情况时,你会发现 HTMLXML 总会打破你的“规则”,这让你很头疼…像这样的话,建议使用 HTML 和 XML 解析器来处理更合适。

使用 re.VERBOSE

现在你应该意识到了,**正则表达式的表示非常紧凑。这也带来了一个问题,就是不好阅读。**中等复杂的正则表达式可能包含许多反斜杠、圆括号和元字符,以至于难以读懂。

在这些 REs 中,当编译正则表达式时指定 re.VERBOSE 标志是非常有帮助的。因为它允许你可以编辑正则表达式的格式,使之更清楚。

re.VERBOSE 标志有几个作用。在正则表达式中不在字符类中的空白字符将被忽略。这就意味着像 I love FishC 这样的表达式和可读性较差的 IloveFishC 相同。但 [a b] 将匹配字符 ‘a’、‘b’ 或 ’ ';另外,你也可以把注释放到 RE 中,注释是从 # 开始到下一行。当使用三引号字符串时,会使得 REs 的格式更整洁:

pat = re.compile(r"""\s*                             # Skip leading whitespace(?P<header>[^:]+)   # Header name\s* :                           # Whitespace, and a colon(?P<value>.*?)          # The header's value -- *? used to# lose the following trailing whitespace\s*$                           # Trailing whitespace to end-of-line
""", re.VERBOSE)

同样的内容,下边这个要难读得多:

pat = re.compile(r"\s*(?P<header>[^:]+)\s*:(?P<value>.*?)\s*$")

Python正则表达式之额外补充(7)相关推荐

  1. [小小明]Python正则表达式速查表与实操手册

    v0.3下载地址:https://download.csdn.net/download/as604049322/14504394 目录 文章目录 文档简介 作者简介 阅读建议 版权声明 Python ...

  2. 正则表达式 - Python 正则表达式 学习笔记 最全整理

    正则表达式 regular expression,用于匹配字符串中字符组成的方法,"用有限的符号表达无限的序列". JavaScript 正则表达式语法如下: /xxx/gi 两条 ...

  3. Python零基础速成班-第13讲-Python正则表达式Regex

    Python零基础速成班-第13讲-Python正则表达式Regex 学习目标 正则表达式 课后作业(4必做) 友情提示:将下文中代码拷贝到JupyterNotebook中直接执行即可,部分代码需要连 ...

  4. Python正则表达式匹配中文

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 参照Py ...

  5. Python正则表达式,看这一篇就够了

    作者 | 猪哥 来源 | 裸睡的猪(ID: IT--Pig) 大多数编程语言的正则表达式设计都师从Perl,所以语法基本相似,不同的是每种语言都有自己的函数去支持正则,今天我们就来学习 Python中 ...

  6. 阅读后这篇文章后,python正则表达式完全弄懂了

    大多数编程语言的正则表达式设计都师从Perl,所以语法基本相似,不同的是每种语言都有自己的函数去支持正则,今天我们就来学习 Python中关于 正则表达式的函数. re模块主要定义了9个常量.12个函 ...

  7. Python正则表达式常用flag含义与用法详解

    封面图片:<Python程序设计实验指导书>(ISBN:9787302525790),董付国,清华大学出版社 图书详情(京东): ================== Python正则表达 ...

  8. 简谈python正则表达式

    这篇文章里,我会尽量用比较浅显易懂的语言和给位看官讨论关于python正则表达式的知识,我们首先来看看什么是正则表达式. 正则:使用单个字符串描述.匹配一系列语法规则的字符串.正则表达式就是用于对一个 ...

  9. 【专题】Python正则表达式re模块使用

    一.从一个需求出发 现在有一个Info.txt的文本信息: 姓名 地区 身局 体重 电话 况咏蜜 北京 171 48 13651054608 王心颜 上海 169 46 13813234424 马纤羽 ...

最新文章

  1. 小学生计算机课堂实践的重要性,多媒体在小学教学中的重要性
  2. java docx word api_javadoc生成word接口文档
  3. linux命令上常用命令
  4. C# 利用反射动态调用类成员
  5. iOS 里面如何使用第三方应用程序打开自己的文件,调用wps其他应用打开当前应用里面的的ppt doc xls...
  6. .NET6之MiniAPI(十五):跨域CORS(下)
  7. 第十届机器学习及其应用研讨会 MLA’2012 Slides
  8. python-面向对向编程-小结
  9. C# 之 Excel 导入一列中既有汉字又有数字:数字可以正常导入,汉字导入为空
  10. yarn 常用命令(干干货!)
  11. 我的世界java版袭击_袭击 - Minecraft Wiki,最详细的官方我的世界百科
  12. jrtplib的使用
  13. CUDA库之NPP(二):NPP实现YUV转BGR
  14. 冲激脉冲抽样定理matlab,信号抽样及抽样定理分析.doc
  15. java selector wakeup_java – 如何检测Selector.wakeup调用
  16. 【css技巧】CSS filter的神奇用法 | 褪色|融合效果等
  17. 数据结构中的“阴”和“阳”
  18. HTML+CSS+JS大作业:网站设计——家具装修公司(12页 bootstrap, 响应式)
  19. html打开方式怎么没有反应,为什么我点开启程序没反应
  20. OnlyS减脂瘦身APP被减肥达人全资收购

热门文章

  1. windows10安装python环境_在windows10下安装python(配置环境变量),Windows10
  2. python idle撤回上一条命令_找回Python IDLE Shell里的历史命令(用上下键翻历史命令怎么不好用了呢?)...
  3. idea前进和后退快捷键_必备技能:IDEA一定要懂的32条快捷键
  4. Python绘图之matplotlib基础教程:matplotlib库图表绘制中常规设置大全(交互模式、清除原有图像、设置横坐标显示文字/旋转角度、添加图例、绘图布局自动调整、图像显示、图像暂停)
  5. ML之UL:无监督学习Unsupervised Learning的概念、应用、经典案例之详细攻略
  6. DayDayUp:《P2P行业最高端的玩法》源于网友网络收集
  7. 成功解决YOLOv3测试——could not create cudnn handle: CUDNN_STATUS_NOT_INITIALIZE作记录
  8. RedisCluster读写分离改造
  9. LSQL Developer连接Oracle11g 64位数据库配置详解
  10. bundle install 出现 #39;gem install mysql2 -v #39;0.3.15#39; succeeds before bunding #39;