我们分别执行三个语句:

>>> 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. python的各版本的不同

    Python的版本主要分为 2.× . 3.× 两个系列. Python3计划每年发布一个新的子版本,一次只增加一两种新语法. 使用时当然选择越新的Python版本越好,版本越老的代码越难维护. 维护 ...

  2. 关于mybatis拦截器,对结果集进行拦截

    因业务需要,需将结果集序列化为json返回,于是,网上找了好久资料,都是关于拦截参数的处理,拦截Sql语法构建的处理,就是很少关于对拦截结果集的处理,于是自己简单的写了一个对结果集的处理, 记录下. ...

  3. Pandas_VBA_数据筛选比较

    Pandas与VBA筛选数据的比较 Author:Collin_PXY 需求: 将B列里值为Completed 和 Pending的A,B,D三列数据筛选出来,新建一个名为 Filited_data的 ...

  4. KMP算法和bfprt算法总结

    目录 1 KMP算法 1.1 KMP算法分析 1.2 KMP算法应用 题目1:旋转词 题目2:子树问题 2 bfprt算法 2.1 bfprt算法分析 2.2 bfprt算法应用 1 KMP算法 大厂 ...

  5. c++ 11字符串与string转换常用函数

    这里主要介绍一下string to int 其他方法与这个类似,可到头文件 <string> 中查看 @_Str 转换的字符串 @_Idx 转换的长度(位数) @_Base 进制 doub ...

  6. 【webSokect】基于django Channels的简单实现

    # settings.py: INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.con ...

  7. 安装vmware tool

    首先简单介绍一下vmware tool的作用: 1.最大的好处是可以直接把windows界面的文件拖进linux虚拟机内. 2.鼠标可以直接从虚拟机移动到windows等等好处. 步骤 1.点击虚拟机 ...

  8. mdtest测试工具

    软件介绍 mdstest是软件的元数据操作基准测试工具,用来模拟对文件或者目录的open.stat.close操作,然后报告性能 下载软件压缩包: yum install openmpi openmp ...

  9. [LeetCode题解]109. 有序链表转换二叉搜索树 | 快慢指针 + 递归

    题目描述 给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: 给定的有序链表: ...

  10. centos 6 系统下同步本地时间

    1.date显示系统时间 [root@oldboy ~]# dateTue Mar 31 22:45:55 CST 2020   #CST是指是指某中标准时间 非东八区时间 更改时间的三种方法 1.c ...