我正在尝试使用正则表达式在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
任何帮助表示赞赏!
答案 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来解析缺失值。