【问题标题】:Regular expression only captures the last occurence of repeated group正则表达式仅捕获重复组的最后一次出现
【发布时间】:2017-10-07 12:14:54
【问题描述】:

我正在尝试从这样的字符串中捕获多个带有Python regular expression 的“ = ”对:

  some(code) ' <tag attrib1="some_value" attrib2="value2"                   en=""/>

正则表达式'\s*&lt;tag(?:\s*(\w+)\s*=\"(.*?)\")* 旨在多次匹配这些对,即返回类似

"attrib1", "some_value", "attrib2", "value2", "en", ""

但它只捕获最后一次出现:

>>> import re
>>> re.search("'\s*<tag(?:\s*(\w+)\s*=\"(.*?)\")*", '  some(code) \' <tag attrib1="some_value" attrib2="value2"                   en=""/>').groups()
('en', '')

专注于 ="" 有效:

>>> re.findall("(?:\s*(\w+)\s*=\"(.*?)\")", '  some(code) \' <tag attrib1="some_value" attrib2="value2"                   en=""/>')
[('attrib1', 'some_value'), ('attrib2', 'value2'), ('en', '')]

所以一个务实的解决方案可能是在运行这个正则表达式之前测试"&lt;tag" in string,但是..

为什么原始的正则表达式只捕获最后一次出现以及需要进行哪些更改才能使其按预期工作?

【问题讨论】:

  • 每周“如何使用正则表达式解析 html/xml”问题...使用 XML 解析器。不要尝试在非正则语言上使用 正则 表达式。
  • 你说得对,问题实际上是关于正则表达式,而不是 XML。
  • 这就是正则表达式的工作原理。它只捕获最后一次出现。您无法使用正则表达式捕获任意数量的事件。编写循环以多次应用正则表达式,或使用 xml 解析器。
  • @Rawing 您能否详细说明为什么它只捕获“答案”中重复组的最后一次出现或提供一些参考?如果引擎“看到”重复组,为什么不捕获它?是否可以选择不覆盖最后一场小组赛?
  • @StutiRastogi 不,但谢谢。顺便说一句:字符串只是可能包含或不包含我要提取的数据的许多行之一,因此它还需要匹配 ' &lt;tag

标签: python regex


【解决方案1】:

documentation 搜索将只返回一次。 findAll 方法返回列表中的所有匹配项。这就是您需要使用的,就像在您的第二个示例中一样。

【讨论】:

  • 没错,但我只需要出现一次:模式应该匹配整个字符串,尽管一组重复多次。 findall 也只返回最后一个匹配项。
  • 模式 does 匹配整个字符串 with 组的重复,不幸的是,这不会产生多个匹配组。
  • 你的目标是什么?你想要只出现一次还是全部出现?第二个例子有什么问题?我不知道您为什么要在 RegEx 中使用
  • 谢谢,但这是两件不同的事情。看看 cmets 和其他答案,它们解决了原来的问题。
  • 我看了他们就明白了,你的问题最初我并不清楚。祝你阅读顺利。
【解决方案2】:

这就是正则表达式的工作原理:您定义了一个捕获组,因此只有一个捕获组。当它先捕获某个东西,然后捕获另一个东西时,第一个捕获的项目将被替换。这就是为什么您只获得最后一个捕获的项目。
我知道没有解决方案...

【讨论】:

    【解决方案3】:

    不幸的是,这对于 python 的 re 模块是不可能的。但是regex为此提供了capturescapturesdict函数:

    >>> m = regex.match(r"(?:(?P<word>\w+) (?P<digits>\d+)\n)+", "one 1\ntwo 2\nthree 3\n")
    >>> m.groupdict()
    {'word': 'three', 'digits': '3'}
    >>> m.captures("word")
    ['one', 'two', 'three']
    >>> m.captures("digits")
    ['1', '2', '3']
    >>> m.capturesdict()
    {'word': ['one', 'two', 'three'], 'digits': ['1', '2', '3']}
    

    【讨论】:

      猜你喜欢
      • 2020-12-16
      • 1970-01-01
      • 2016-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-21
      • 2019-04-25
      • 2012-01-12
      相关资源
      最近更新 更多