Python正则表达式 r'(.*) are (.*?) .*' 贪婪与非贪婪模式解析

Theo
Theo
发布时间:2026-10-15| 5人浏览过
原创

本文深入解析Python中正则表达式 r'(.*) are (.*?) .*' 的匹配机制。通过对比贪婪模式 (.*) 与非贪婪模式 (.*?) 的行为,结合多个代码示例,详细阐述分组捕获、无分组匹配及多are分隔符下的匹配结果差异,帮助开发者准确掌握正则表达式的核心逻辑。

正则表达式 r'(.*) are (.*?) .*' 基础解析

在Python3正则表达式的学习过程中,常会遇到一个经典示例。

#!/usr/bin/python3
import re
 
line = "Cats are smarter than dogs"
# .* 表示任意匹配除换行符(\n、\r)之外的任何单个或多个字符
# (.*?) 表示"非贪婪"模式,只保存第一个匹配到的子串
matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)
 
if matchObj:
   print ("matchObj.group() : ", matchObj.group())
   print ("matchObj.group(1) : ", matchObj.group(1))
   print ("matchObj.group(2) : ", matchObj.group(2))
else:
   print ("No match!!")

该示例的运行结果如下。

matchObj.group() : Cats are smarter than dogs matchObj.group(1) : Cats matchObj.group(2) : smarter

该例子的核心正则表达式为 r'(.*) are (.*?) .*'。以下结合查阅的资料与实验结果,阐述个人理解。

  1. 前缀 r 表示原始字符串,即忽略转义字符,使编译器不处理反斜杠。但在本例中字符串不含反斜杠,因此 r 前缀可选。
  2. (.*) 是第一个匹配分组,.* 代表匹配除换行符(\n、\r)之外的所有字符。
  3. (.*?) 是第二个匹配分组,.*? 后的问号表示非贪婪模式,即仅匹配符合条件的最少字符。
  4. 末尾的 .* 未被括号包围,因此不构成分组,其匹配效果与第一个 .* 类似,但不计入匹配结果。

综上所述,该正则表达式以 are 为分隔点将字符串分为几部分:(.*?) 因贪婪模式返回所有满足条件的内容,而 (.*?) 因非贪婪模式仅返回第一个满足要求的内容或为空。

贪婪与非贪婪模式对比示例

若对匹配成功机制尚不理解,可参考以下示例。

  #!/usr/bin/python3
  
  import re
   
  #line = "Cats are smarter than dogs"
  line = "a a Cats are Cats are smarter than dogs"
  # .* 表示任意匹配除换行符(\n、\r)之外的任何单个或多个字符
  # (.*?) 表示"非贪婪"模式,只保存第一个匹配到的子串
  matchObj = re.match( r'(.*) are (.*) .*', line, re.M|re.I)
   
  if matchObj:
      print ("matchObj.group() : ", matchObj.group())
      print ("matchObj.group(1) : ", matchObj.group(1))
      print ("matchObj.group(2) : ", matchObj.group(2))
  else:                                                                      
      print ("No match!!")

输出结果如下。

matchObj.group() : a a Cats are Cats are smarter than dogs matchObj.group(1) : a a Cats are Cats matchObj.group(2) : smarter than

此例主要对第一个示例中的 line 字符串进行观察,并展示输出结果。

group(1) 对应第一个括号的条件,可理解为最后满足 are 分段前的所有内容。若将第一个括号改为 (.*?),则匹配第一个 are 前面的内容,经验证确实如此,此处省略代码供读者自行验证。

多分组与无分组匹配的深入分析

以下示例旨在进一步解释第二个括号内容及无括号的 .* 的作用。

 #!/usr/bin/python3
  
  import re
   
  #line = "Cats are smarter than dogs"
  line = "a a Cats are Cats are smarter than dogs"
  # .* 表示任意匹配除换行符(\n、\r)之外的任何单个或多个字符
  # (.*?) 表示"非贪婪"模式,只保存第一个匹配到的子串
  matchObj = re.match( r'(.*?) are (.*) .* .*', line, re.M|re.I)             
   
  if matchObj:
      print ("matchObj.group() : ", matchObj.group())
      print ("matchObj.group(1) : ", matchObj.group(1))
      print ("matchObj.group(2) : ", matchObj.group(2))
  else:
      print ("No match!!")

matchObj.group() : a a Cats are Cats are smarter than dogs matchObj.group(1) : a a Cats matchObj.group(2) : Cats are smarter

group(2) 对应第二个括号的条件:由于第一个括号内容添加了 ?,其索引内容为第一个 are 前面的部分;第二个括号则从当前 are 之后开始索引。此处未加 ?,因此输出为 .* 条件后的所有内容。

.* 因无 () 无法通过 group 访问,但会实际占用位置。上述示例最后使用两个 .*,因此最后占用两个单词,剩余部分即为 group(2) 的输出内容。

多are分隔符下的匹配验证

读者可自行尝试在语句中增加多个 are,并观察修改 ? 或括号后的效果。

  #!/usr/bin/python3
  
  import re
  
  #line = "Cats are smarter than dogs"
  line = "a a Cats are CatsB are smarter are than are dogs are dogs b c d e"
  # .* 表示任意匹配除换行符(\n、\r)之外的任何单个或多个字符
  # (.*?) 表示"非贪婪"模式,只保存第一个匹配到的子串
  matchObj = re.match( r'(.*?) are (.*?) (.*?) (.*) .*', line, re.M|re.I)    
   
  if matchObj:
      print ("matchObj.group() : ", matchObj.group())
      print ("matchObj.group(1) : ", matchObj.group(1))
      print ("matchObj.group(2) : ", matchObj.group(2))
      print ("matchObj.group(3) : ", matchObj.group(3))
      print ("matchObj.group(4) : ", matchObj.group(4))
  else:
      print ("No match!!")

matchObj.group() : a a Cats are CatsB are smarter are than are dogs are dogs b c d e matchObj.group(1) : a a Cats matchObj.group(2) : CatsB matchObj.group(3) : are matchObj.group(4) : smarter are than are dogs are dogs b c d

总结。

至此,关于Python正则表达式 r'(.*) are (.*?) .*' 的深入理解介绍完毕。更多相关内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。