re.findall中不能使用子表达式?

findall使用()作为子表达式没有效果

>>> print re.findall("(luo){2}","aboluoaboluoluoluoa")
['luo']

而search就可以

>>> print re.search("(luo){2}","aboluoaboluoluoluoa").span()
(9, 15)

是不是哪里写错了?

阅读 3.8k
3 个回答

span方法只是表明匹配的结果, 在原序列中开始位置和结束位置而已. 如果你想得到结果luo luo, 你可以试下:


import re
print re.findall("((?:luo){2})","aboluoaboluoluoluoa")
In [12]: print re.findall(r"(luo)(luo)","aboluoaboluoluoluoa")
[('luo', 'luo')] # 两个分组,匹配luoluo,出现一次,显示分组内表达式匹配的内容('luo', 'luo')

In [13]: print re.findall(r"luo","aboluoaboluoluoluoa") 
['luo', 'luo', 'luo', 'luo'] # 没有分组,匹配luo,出现四次,显示四次。

In [14]: print re.findall(r"(luo)","aboluoaboluoluoluoa")
['luo', 'luo', 'luo', 'luo'] # 一个分组,匹配luo,出现4次。

In [15]: print re.findall(r"(luo){2}","aboluoaboluoluoluoa")
['luo'] # 一个分组,一个分组 ,匹配luoluo,匹配luoluo,显示分组内表达式匹配的结果 luo

也就是说,(luo){2}的子表达式是"luo",相当于"(luo)luo",而不是(luoluo)。如果想匹配出luoluo,(?:luo){2}才是你想要的。

re.findall 是一个方便的方法,如果你的正则有捕获组,那么它只返回捕获组的内容,而不返回整个匹配。

你可以选择:

  • 使用非捕获组((?:...)
  • 把你需要的东西放到捕获组中(((?:luo){2})
  • 使用 re.finditer 方法。这个方法返回的是完整的 match 对象
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题