捕获第一组旁边的可选捕获组

时间:2018-02-08 21:29:37

标签: regex capture-group

给出两个字符串

hello/world/thomas

hello/world

我有以下正则表达式

hello/(.+)(/(.+))?

第二组是可选的。

我希望以下小组匹配:

['world', 'thomas']

但我得到了:

['world/thomas']

第二个字符串按预期工作:

['world']

如何产生预期结果。

https://regexr.com/3kh06

1 个答案:

答案 0 :(得分:0)

您的模式 - hello/(.+)(/(.+))? - 匹配hello/,然后(.+)抓取该行的所有其余部分,将其放入第1组,然后检查它是否可以与文本的其余部分匹配(此时,使用(/(.+))?模式的字符串末尾的空文本 - 因为?量词可以匹配空字符串(= 零或更多重复) )。

您可以将.替换为[^/] negated character class,以避免匹配换行符以外的所有字符:

var rx = new RegExp("hello/([^/]+)(?:/([^/]+))?", "g")

请参阅regex demo

<强>描述

  • hello/ - 文字子字符串
  • ([^/]+) - 第1组:/
  • 以外的任何一个或多个字符
  • (?:/([^/]+))? - 一个可选的非捕获组,匹配1或0次出现
    • / - /字符
    • ([^/]+) - 第2组:/以外的一个或多个字符。

JS演示:

var strs = ['hello/world/thomas', 'hello/world'];      // Demo strings
var rx = new RegExp("hello/([^/]+)(?:/([^/]+))?", "g") // Regex (constructor used due to many / inside
for (var s of strs) {                                  // Demo loop
  var res = [], m;
  while(m = rx.exec(s)) {                              // Check for multiple matches
    res.push(m[1]);                                    // Adding Group 1 to results
    if (m[2]) res.push(m[2]);                         // Adding Group 2 to results if exists
  }
  console.log(s, res);                                // Demo result display
  
}