正则表达式 - 重复捕获组

Posted

技术标签:

【中文标题】正则表达式 - 重复捕获组【英文标题】:Regex - Repeating Capturing Group 【发布时间】:2017-09-13 15:43:45 【问题描述】:

我试图弄清楚如何在以下 url 字符串中的 comma-separated 值上重复捕获组:

id=1,2;name=user1,user2,user3;city=Oakland,San Francisco,Seattle;zip=94553,94523;

我正在使用这个RegExp,这是我想要的返回结果,除了值,因为它们是动态的,即。在 url 参数中可能是 2、3、4 等用户,我想知道是否可以为每个值创建一个捕获组,而不是 user1,user2,user3 作为一个捕获组。

正则表达式: (^|;|:)(\w+)=([^;]+)*

这是使用 RegExp

在线进行的现场演示

示例输出:

Group1 -(分号,冒号) Group2 -(密钥,即 id、name、city、zip) Group3 - (value1) Group4 - (value2) *如果存在 Group5 - (value3) *如果存在 Group6 - (value4) *如果存在

等等...基于我之前解释的动态值。

问题:我的表达有什么问题我使用 * 循环重复模式?

【问题讨论】:

您的预期输出是什么?我认为这可以在不使用正则表达式的情况下完成。 您是否期望得到如下结果: "id": ["1", "2"], "name": ["user1", "user2", "user3"], "city": ["Oakland", "San Francisco", "Seattle"], "zip": ["94553", "94523"] @ibrahimmahrir 我在上面给出了示例输出,这些值是动态的,如user1,user2,etc... 所以基本上希望每个值都在它自己的capture-group 不!我说的是最终输出而不是正则表达式的输出。您希望数据最终看起来如何? 这是你想要做的regex101.com/r/2HQ8dv/2 【参考方案1】:

Regex 不支持您尝试执行的操作。当引擎第二次进入捕获组时,它会覆盖第一次捕获的内容。考虑一个简单的例子(感谢regular-expressions.info):/(abc|123)+/ 用于'abc123'。它将匹配“abc”,然后查看加号并重试,匹配“123”。输出中的最终捕获组将是“123”。

无论您尝试什么模式,当正则表达式接受字符串时,您设置的任何限制都会发生这种情况。考虑/(abc|123)2/。这接受捕获组为“123”的“abc123”,但不接受“abc123abc”。将捕获组放在另一个组中也不起作用。创建捕获组时,就像创建变量一样。它只能有一个值,后续值会覆盖前一个值。您永远无法拥有比括号对更多的捕获组(不过,您绝对可以拥有更少)。

然后一个可能的解决方法是拆分';'上的字符串,然后拆分'='上的每个字符串,然后拆分','上的右侧。那会让你[['id', '1', '2'], ['name', 'user1', ...], ['city', ...], ['zip', ...]]

结果是:

function (str) 
  var afterSplit = str.split(';|:');
  afterSplit.pop() // final semicolon creates empty string
  for (var i = 0; i < afterSplit.length; i++) 
    afterSplit[i] = afterSplit[i].split('=');
    afterSplit[i][1] = afterSplit[i][1].split(','); // optionally, you can flatten the array from here to get something nicer
  
  return afterSplit;

【讨论】:

虽然捕获组不重复,但在某些情况下您可以简单地复制捕获组。例如,假设我正在解析源代码,并且我想匹配一个类声明以获取实现的接口:X 类实现 A、B、C、D。您可以创建捕获组(?:,\s+([^\s]+))?(匹配零次或一次)并重复它...(?:,\s+([^\s]+))?(?:,\s+([^\s]+))?(?:,\s+([^\s]+))? 现在将匹配最多 3 个已实现的类。在 python 中它更容易,因为你可以像pattern = '(?:,\s+([^\s]+))?' * 3 etc/ 那样做【参考方案2】:

重复捕获组

字符串:!abc123def! 正则表达式:/!((abc|123|def)+)!/

匹配:

第 1 组:abc123def

第 2 组:定义

来源:https://www.regular-expressions.info/captureall.html

【讨论】:

以上是关于正则表达式 - 重复捕获组的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式 - 重复捕获组

正则表达式组捕获[重复]

正则表达式:如何在捕获单个组时匹配整个字符串 [重复]

Python正则表达式-或在捕获组中间[重复]

.Net 正则表达式用捕获组替换重复出现的模式

c# 正则表达式捕获