【问题标题】:Clarification on Python regexes and findall()关于 Python 正则表达式和 findall() 的说明
【发布时间】:2012-07-21 21:51:32
【问题描述】:

我在处理Python Challenge 时遇到了这个问题。准确地说是10号。我决定尝试使用正则表达式来解决它 - 提取重复序列,计算它们的长度,然后构建序列中的下一个项目。

所以我开发的正则表达式是:'(\d)\1*'

它在在线regex tester 上运行良好,但在我的脚本中使用它时,它并没有执行相同的操作:

regex = re.compile('(\d)\1*')
text = '111122223333'
re.findall(regex, text)

> ['1', '1', '1', '1', '2', '2', '2',...]

等等等等。所以我在 Python 的 re 模块中了解了原始类型。这是我的第一个问题:有人可以解释一下这到底是做什么的吗?该文档将其描述为减少了转义反斜杠的需要,但对于更简单的正则表达式(例如\d+)似乎不需要它,我不明白为什么。

所以我将我的正则表达式更改为r'(\d)\1*',现在尝试使用findall() 来制作序列列表。我得到了

> ['1', '2', '3']

又是一头雾水。我还是不明白这一点。请帮忙?

我决定这样做是为了解决这个问题:

[m.group() for m in regex.finditer(text)]
> ['1111', '2222', '3333']

然后得到我一直在寻找的东西。然后,基于this 线程,我尝试将findall() 添加一个组到整个正则表达式-> r'((\d)\2*)'。 我最终得到:

> [('1111', '1'), ('2222', '2'), ('3333', '3')]

在这一点上,我很困惑。我知道这个结果与多个组有关,但我不确定。

另外,这是我第一次发帖,如果我的礼仪不正确,我深表歉意。请随时纠正我。谢谢!

【问题讨论】:

  • 您应该避免像这样将多个问题混在一起,这会使它们更难理解。最好单独发布简单的问题。您还应该指出您期望的结果,而不是仅仅说您对得到的结果感到困惑。
  • “我遇到了这个问题...我决定使用正则表达式来解决它...”您现在有多少问题?
  • @DanielRoseman:就 Python Challenge 问题 10 而言,正则表达式是解决问题的好方法。如果您了解 re 模块实际上为您提供了什么......
  • 陈述问题。在第一行陈述它。不要强迫我们坐下来阅读一篇文章并参考pythonchallenge.com的问题,所以我们必须去解决问题0..9,只是为了得到陈述你的问题。嗯。如果你想写关于代码的文章,把它放在博客上。该网站用于问答。不要写“我做了 X。然后我读了 Z。所以我尝试了 Y。我很困惑。”而是写“我正在尝试做 A,结果应该看起来像 B,为什么代码 C 会产生 D?”

标签: python regex findall


【解决方案1】:

由于这是一个挑战,我不会给你一个完整的答案。但是,您走在正确的轨道上。

finditer 方法返回MatchObject instances。您想查看这些上的.group() method 并仔细阅读文档。想想那里的.group(0).group(1) 有什么区别;普通的.group().group(0) 相同。

至于\d转义字符;因为特定的转义组合作为 Python 字符串转义字符没有任何意义,Python 会忽略它并将其保留为反斜杠和字母 d。使用r'' 文字字符串格式确实会更好,因为当您确实想要使用正则表达式字符集时,它可以防止令人讨厌的意外,而该字符集恰好也是python可以识别的转义序列.请参阅python documentation on string literals for more information

您的 .findall()r'((\d)\2*)' 表达式在每个匹配项中返回 2 个元素,因为您的模式中有 2 个组;外部的整个组匹配(\d)\2*,内部组匹配\d。来自.findall() documentation

如果模式中存在一个或多个组,则返回组列表;如果模式有多个组,这将是一个元组列表。

【讨论】:

  • 你说那个转义组合没有意义是什么意思?我仍然没有掌握这一点。它是否被识别为数字字符类? (当你不使用原始格式时)
  • @Louis:它具有作为正则表达式类的意义,但不是作为 python 转义序列(就像\n 一样,那是一个换行符)。
  • @Martin:我明白了,谢谢。我现在唯一无法理解的是为什么findall() 会产生我提到的第二个结果。
  • @Louis:因为你最终有两个匹配组,(\d)\2*\d
猜你喜欢
  • 2011-07-18
  • 1970-01-01
  • 2015-08-13
  • 2011-12-06
  • 1970-01-01
  • 1970-01-01
  • 2013-07-10
  • 2011-12-27
  • 2013-07-10
相关资源
最近更新 更多