具有可选捕获字段的正则表达式

时间:2016-12-15 11:08:48

标签: javascript regex

我正在尝试使用正则表达式在javascript中使用正则表达式从字符串中捕获数字。我已经构建了一个字符串,只捕获所有字段存在时的数字:

目标字符串: 3名成人,2名儿童,1名婴儿

正则表达式模式:([1-9])(?:.Adults?.*)([1-9])(?:.Child.*)([1-9])(?:.Infant.*)

我想捕获的内容: [3,2,1]

然而,在目标字符串中,只有成人部分始终存在于字符串中,儿童和婴儿可能不存在。

对于目标字符串,我希望能够处理:

3名成人,1名婴儿

返回: [3,0,1] 或者 [3,,1]

3名成年人

返回 [3,0,0] ,或者 [3]

1名成人,1名儿童,2名婴儿

返回 [1,1,2]

我已尝试将儿童和婴儿部分包装在其自己的组中,以尝试使其成为可选项:

([1-9])(?:.Adults?.*)(([1-9])(?:.Child.*))?(([1-9])(?:.Infant.*))?

但在这种情况下,它似乎与任何目标字符串都没有匹配。

我正在尝试做什么?如果不匹配,Regex可以返回占位符值或空值,以便如果没有子项,婴儿计数不会向前移动到返回值的子位置吗?

我创建了一个包含测试字符串的regex101页面,但我似乎没有取得多大进展:https://regex101.com/r/8NSYMc/1

任何帮助表示赞赏!

2 个答案:

答案 0 :(得分:1)

您可以使用

(\d+)\s+Adults?(?:,\s*(\d+)\s+Child(?:ren)?)?(?:,\s*(\d+)\s+Infant)?

请参阅regex demo

<强>详情:

  • (\d+) - 第1组:一个或多个数字
  • \s+Adults? - 1 +个空格,Adult和可选的s
  • (?:,\s*(\d+)\s+Child(?:ren)?)? - 一个可选的非捕获组,匹配以下序列:
    • ,\s* - 逗号和0+空格
    • (\d+) - 第2组:一个或多个数字
    • \s+Child(?:ren)? - 1 +个空格,Child和可选的ren子字符串
  • (?:,\s*(\d+)\s+Infant)? - 一个可选的非捕获组,匹配以下序列:
    • ,\s* - 逗号和0+空格
    • (\d+) - 第3组:一个或多个数字
    • \s+Infant - 1+个空格和Infant子字符串。

答案 1 :(得分:1)

Wiktor已经提供了答案,但我会解释原始正则表达式的问题。

首先,重要的是要知道匹配在默认情况下是贪婪的,也就是说,正则表达式尝试尽可能匹配。因此,.*构造有点危险,因为它可能会比预期吞下更多。

由于儿童和婴儿群体在开始时是强制性的,这将限制贪婪的比赛可以吞咽的文本,同时仍然匹配所有部分。但是,在你选择了部件之后,成人部分的贪婪会消耗掉其余部分,而另外两部分将不再匹配。

这就是为什么Wiktor的解决方案使用显式文本而不是匹配所有.。另外,为了避免在结果中移动匹配,您应该使可选组不捕获,例如从(?:开始。

至于占位符:不,你不能,但在JS中处理它很容易,因为你可以做Number(match[1] || 0)例如用默认值0来解析缺失值。