【问题标题】: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

标签: javascript regex capture-group


【解决方案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

【讨论】:

    猜你喜欢
    • 2011-03-11
    • 2017-01-07
    • 2019-12-19
    • 1970-01-01
    • 2011-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-16
    相关资源
    最近更新 更多