如何捕获多个重复组?

phb*_*lov 51 regex regex-group nsregularexpression regex-greedy swift

我需要捕获相同模式的多个组.假设,我有一个以下字符串:

HELLO,THERE,WORLD
Run Code Online (Sandbox Code Playgroud)

我写了一个以下模式

^(?:([A-Z]+),?)+$
Run Code Online (Sandbox Code Playgroud)

我想要它做的是,捕获每一个单词,以便第1组是:"你好",第2组是"THERE"而第3组是"WORLD"我的正则表达式实际上只捕获最后一个,这是"世界".

我测试我的正则表达式在这里,我想与斯威夫特使用它(也许有斯威夫特一种方式来获得中间结果不知怎么的,这样我就可以使用它们?)

更新:我不想使用split.我现在只需要捕获所有匹配模式的组,而不仅仅是最后一组.

Byt*_*der 39

如果模式中有一个组,则只能在该组中获得一个精确结果.如果您的捕获组被模式重复(您+在周围的非捕获组上使用了量词),则只存储与其匹配的最后一个值.

您必须使用语言的正则表达式实现函数来查找模式的所有匹配项,然后您必须删除非捕获组的锚点和量词(并且您也可以省略非捕获组本身).

或者,展开你的正则表达式,让模式包含你想要在结果中获得的每个组的一个捕获组:

^([A-Z]+),([A-Z]+),([A-Z]+)$
Run Code Online (Sandbox Code Playgroud)

  • 如何调整以适应不同数量的字符串?例如,HELLO,WORLD和HELLO,THERE,MY,WORLD.我正在寻找一个表达式来处理这两个示例,并且内置了更长的字符串数组的灵活性 (9认同)
  • 真是遗憾,您只列出了_Alternatively_的代码,而不列出了答案本身。 (4认同)
  • @Chris不能一概而论。如答案所示,捕获组只能捕获一件事,并且无法创建动态数量的捕获组。 (3认同)
  • Re“_如何调整它以适应不同数量的字符串?_”——对于那些仍然访问此页面的人——使用手头语言的工具动态构建它。将子模式(此处为“([AZ]+)”)作为字符串或正则表达式模式(取决于语言)并连接其中 N 个(在本例中使用逗号),然后将其转换为正则表达式模式或只需在正则表达式中使用它(同样,取决于语言)。它通常相当简单。(我认为这个答案认为这是理所当然的,可以动态构建它。) (2认同)

sse*_*nt1 14

关键区别是重复捕获的组而不是捕获重复的组

正如您已经发现的,不同之处在于重复捕获的组仅捕获最后一次迭代。捕获重复组捕获所有迭代。

在 PCRE (PHP) 中:

((?:\w+)+),?
Run Code Online (Sandbox Code Playgroud)
Match 1, Group 1.    0-5      HELLO
Match 2, Group 1.    6-11     THERE
Match 3, Group 1.    12-20    BRUTALLY
Match 4, Group 1.    21-26    CRUEL
Match 5, Group 1.    27-32    WORLD
Run Code Online (Sandbox Code Playgroud)

由于所有捕获都在组 1 中,因此您只需要$1替换。

我使用了这个正则表达式的以下一般形式:

((?:\w+)+),?
Run Code Online (Sandbox Code Playgroud)

regex101 中的示例

  • “捕获重复的组就捕获了所有迭代。” 在你的 regex101 中尝试用 `(\w+),?` 替换你的正则表达式,它会给你相同的结果。这里的关键是“g”标志,它重复您的模式以匹配多个组。 (2认同)

Tim*_*eed 7

我想你需要这样的东西......

b="HELLO,THERE,WORLD"
re.findall('[\w]+',b)
Run Code Online (Sandbox Code Playgroud)

哪个在 Python3 中会返回

['HELLO', 'THERE', 'WORLD']
Run Code Online (Sandbox Code Playgroud)

  • `re.findall('\w+',b)` 短了 2 个字符。不需要字符类,因为您只有一个表达式 (13认同)
  • 但问题没有 python 标签 (4认同)

Uly*_* BN 5

读完Byte Commander 的回答后,我想介绍一个可能的微小改进:

您可以生成一个匹配任一n单词的正则表达式,只要您n是预先确定的。例如,如果我想匹配 1 到 3 个单词,则正则表达式:

^([A-Z]+)(?:,([A-Z]+))?(?:,([A-Z]+))?$
Run Code Online (Sandbox Code Playgroud)

将匹配接下来的句子,包含一个、两个或三个捕获组。

^([A-Z]+)(?:,([A-Z]+))?(?:,([A-Z]+))?$
Run Code Online (Sandbox Code Playgroud)

您可以在 Regex101 上查看有关此正则表达式的完整详细说明。

正如我所说,使用您最喜欢的语言为您想要的任何组生成此正则表达式非常容易。由于我不是一个敏捷的人,这里有一个 ruby​​ 示例:

HELLO,LITTLE,WORLD
HELLO,WORLD
HELLO
Run Code Online (Sandbox Code Playgroud)

split话虽这么说,我建议在这种情况下不要使用正则表达式,根据您的需要,还有许多其他很棒的工具,从简单到一些标记化模式。恕我直言,正则表达式不是其中之一。例如在红宝石中我会使用类似str.split(",")str.scan(/[A-Z]+/)