且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

正则表达式 - 重复捕获组

更新时间:2022-05-10 21:34:36

Reg ex不支持你想要做的事情。当引擎第二次进入捕获组时,它会覆盖第一次捕获的内容。考虑一个简单的例子(感谢 regular-expressions.info ): /(abc | 123)+ / 用于'abc123'。它将匹配abc然后看到加号并重试,匹配123。输出中的最终捕获组将为123。

Regex doesn't support what you're trying to do. When the engine enters the capturing group a second time, it overwrites what it had captured the first time. Consider a simple example (thanks regular-expressions.info): /(abc|123)+/ used on 'abc123'. It will match "abc" then see the plus and try again, matching the "123". The final capturing group in the output will be "123".

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

This happens no matter what pattern you try and any limitation you set simply changes when the regex will accept the string. Consider /(abc|123){2}/. This accepts 'abc123' with the capturing group as "123" but not 'abc123abc'. Putting a capturing group inside another doesn't work either. When you create a capturing group, it's like creating a variable. It can only have one value and subsequent values overwrite the previous one. You'll never be able to have more capturing groups than you have parentheses pairs (you can definitely have fewer, though).

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

A possible fix then would be to split the string on ';', then each of those on '=', then the right-hand side of those on ','. That would get you [['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;
}