我们分别执行三个语句:

>>> re.findall('(.)*',"abc")
['c', '']
>>> re.findall('(.*)',"abc")
['abc', '']
>>> re.findall('(.?)*',"abc")
['', '']
>>>

可以看到三个执行结果完全不同,为什么会这样呢?老猿才开始没弄明白。我们使用《妙用re.sub分析正则表达式解析匹配过程》介绍的方法parsematch来分析一下这三个匹配语句:

>>> parsematch('(.)*',"abc")
第1次匹配,匹配情况:
匹配子串group(0): abc,位置为:(0, 3)
匹配子串group(1): c,位置为:(2, 3)
第2次匹配,m.lastindex=None,匹配情况:
匹配子串group(0): ,位置为:(3, 3) 可以看到“(.)*”是每次匹配一个字母,再重复匹配过程直到匹配不到字母前停止,所以最后匹配结果是字符“c”,在“c”之后是空字符串,由于*的原因也会匹配成功。 >>> parsematch('(.*)',"abc")
第1次匹配,匹配情况:
匹配子串group(0): abc,位置为:(0, 3)
匹配子串group(1): abc,位置为:(0, 3)
第2次匹配,匹配情况:
匹配子串group(0): ,位置为:(3, 3)
匹配子串group(1): ,位置为:(3, 3)

可以看到“(.*)”是第一次匹配是匹配所有字符"abc",匹配到搜索文本结束,第二次匹配空字符串也是匹配成功。

>>> parsematch('(.?)*',"abc")
第1次匹配,匹配情况:
匹配子串group(0): abc,位置为:(0, 3)
匹配子串group(1): ,位置为:(3, 3)
第2次匹配,匹配情况:
匹配子串group(0): ,位置为:(3, 3)
匹配子串group(1): ,位置为:(3, 3)
>>>

可以看到“(.?)*”是每次匹配0-1个字符,再执行星号指定的重复匹配过程直到匹配到“c”之后,由于“abc”[3:3]也能匹配成功,因此最后匹配结果是空串。

第2次匹配“c”之后的空串开始,也是匹配成功,因此又会匹配到空串。

这是parsematch解析的匹配过程,但为什么会这样呢?这是由于匹配过程的优先级决定的,由于括号优先级高于“*”,因此匹配时先优先执行括号内的正则表达式匹配,括号内正则表达式匹配完之后再执行括号外的正则表达式的匹配。所以这三个才会有不同的处理结果。

其实关于正则表达式优先级的事情老猿才开始没有意识到,正是由于这三个语句的执行结果不同才引发了老猿的关注,最终补充了正则表达式优先级的知识章节。

本节相关知识:

  1. 关于正则表达式优先级请参考《第11.26 Python正则表达式运算符优先级》;
  2. 正则表达式解析匹配过程请参考《妙用re.sub分析正则表达式解析匹配过程》;
  3. 贪婪模式和非贪婪模式的匹配处理过程请参考《Python正则表达式W+和W*匹配过程的深入分析》的相关分析。

老猿Python,跟老猿学Python!

博客地址:https://blog.csdn.net/LaoYuanPython


请大家多多支持,点赞、评论和加关注!谢谢!

Python正则运算符优先级re.findall('(.)*',"abc")、re.findall('(.*)',"abc")、re.findall('(.?)*',"abc")的执行结果的影响分析的更多相关文章

  1. 介绍python中运算符优先级

    下面这个表给出Python的运算符优先级,从最低的优先级(最松散地结合)到最高的优先级(最紧密地结合).这意味着在一个表达式中,Python会首先计算表中较下面的运算符,然后在计算列在表上部的运算符. ...

  2. 第11.26节 Python正则表达式运算符优先级

    正则表达式从左到右进行计算,并遵循优先级顺序,相关运算符的优先级顺序按下表从高到低排列. 例如:字符具有高于替换运算符的优先级,使得"m|food"匹配"m"或 ...

  3. python运算符优先级

    下面这个表给出Python的运算符优先级,从最低的优先级(最松散地结合)到最高的优先级(最紧密地结合).这意味着在一个表达式中,Python会首先计算表中较下面的运算符,然后在计算列在表上部的运算符. ...

  4. Python 运算符优先级

    这个表给出Python的运算符优先级(从低到高). 从最低的优先级(最松散地结合)到最高的优先级(最紧密地结合). 这意味着在一个表达式中,Python会首先计算表中较下面的运算符,然后在计算列在表上 ...

  5. Python算术运算符

    Python 运算符 什么是运算符? 本章节主要说明Python的运算符.举个简单的例子 4 +5 = 9 . 例子中,4和5被称为操作数,"+"号为运算符. Python语言支持 ...

  6. Day2 Python的运算符及三大语句控制结构

    Python的运算符 Python语言支持以下类型的运算符: 算术运算符 比较(关系)运算符 赋值运算符 逻辑运算符 位运算符 成员运算符 身份运算符 运算符优先级 Python的三大语句控制结构: ...

  7. python 之 运算符

    Python 运算符   Python 运算符 什么是运算符? 本章节主要说明Python的运算符.举个简单的例子 4 +5 = 9 . 例子中,4和5被称为操作数,"+"号为运算 ...

  8. python的运算符及优先级与python的表达式

    什么是运算符 >>在Python中,我们对一个或者是多个数字或字符串进行操作的符号 运算符有哪些 >>在Python中我们常见的运算符有:+.-.*./.**.<.> ...

  9. python正则之match search findall

    match:只匹配一次,开头匹配不上,则不继续匹配 a,b,\w+ match(a,"abcdef") 匹配a >>> re.match("a" ...

随机推荐

  1. odbc。INI配置

    [ODBC Data Sources] ST = OSCAR ODBC DRIVER [ST] Driver = /opt/ShenTong/odbc/lib/liboscarodbcw.so Ser ...

  2. leetcode148two-sum

    Given an array of integers, find two numbers such that they add up to a specific target number. The ...

  3. 限制页面只能由微信内置浏览器打开,在其他浏览器打开跳转到Oauth2页面

    在需要限制的页面加上  appid必填,可以获取也可以自己随意 <script> var ua = navigator.userAgent.toLowerCase(); var isWei ...

  4. python_摘要_加密

    import hashlib def get_md5(username,password): md5 = hashlib.md5(username.encode('utf-8')) # 加盐 md5. ...

  5. 从零开始实现ASP.NET Core MVC的插件式开发(九) - 升级.NET 5及启用预编译视图

    标题:从零开始实现ASP.NET Core MVC的插件式开发(九) - 如何启用预编译视图 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/1399 ...

  6. 04 . Vue组件注册,数据交互,调试工具及组件插槽介绍及使用

    vue组件 组件(Component)是 Vue.js 最强大的功能之一. 组件可以扩展 HTML 元素,封装可重用的代码. 组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的 ...

  7. Why use MSIX message signal interrupt

    处理一个低版本内核中断向量表不够问题:__assign_irq_vector 关联irq 和 vector失败问题: (bug还没解决先记录一下吧) 同时先学习一下MSI-X:MSI, message ...

  8. socket connect tcp_v4_connect

    tcp_v4_connect /* This will initiate an outgoing connection. tcp_v4_connect函数初始化一个对外的连接请求,创建一个SYN包并发 ...

  9. innodb为什么需要doublewrite(转)

    InnoDB的page size默认是16KB,而操作系统的一个block size是4KB,磁盘io block则更小.那么InnoDB的page刷到磁盘上要写4个操作系统block,在极端情况下( ...

  10. 双数组字典树(Double Array Trie)

    参考文献 1.双数组字典树(DATrie)详解及实现 2.小白详解Trie树 3.论文<基于双数组Trie树算法的字典改进和实现> DAT的基本内容介绍这里就不展开说了,从Trie过来的同 ...