Javascript 正则表达式:使用单个匹配捕获多个可选组

Javascript 正则表达式:使用单个匹配捕获多个可选组,javascript,regex,Javascript,Regex,在JavaScript中,我正在寻找一个正则表达式来捕获字符串中的多个可选组。但至少有一个团体应该存在 字符串:foo bar 12秒3分钟4小时 到目前为止的正则表达式:/?:\d+\s?s?:秒:\d+\s?m?:分钟:\d+\s?h?:我们的?/gi 我需要捕获12秒3分钟和4小时,只返回各自组中的数值 这些时间单位可以存在,也可以交换。我的最终结果需要如下所示: 12s 3m/['12','3',未定义] 10秒/['10',未定义,未定义] 4小时//[未定义,未定义,'4'] 3分钟

在JavaScript中,我正在寻找一个正则表达式来捕获字符串中的多个可选组。但至少有一个团体应该存在

字符串:foo bar 12秒3分钟4小时

到目前为止的正则表达式:/?:\d+\s?s?:秒:\d+\s?m?:分钟:\d+\s?h?:我们的?/gi

我需要捕获12秒3分钟和4小时,只返回各自组中的数值

这些时间单位可以存在,也可以交换。我的最终结果需要如下所示:

12s 3m/['12','3',未定义] 10秒/['10',未定义,未定义] 4小时//[未定义,未定义,'4'] 3分钟//[未定义,'3',未定义] 1小时54秒7分钟/['54','7','1'] 未定义的null或空字符串。只要它们在各自的索引中


有没有简单的方法可以通过单个exec或match而不使用循环来处理这一问题?

不确定这是否与各种类型的输入字符串匹配,但我为您在那里输入的字符串想出了一些方法。我假设秒在前面,分钟在后面,小时在你的问题输入字符串中。这个订单一直正确吗

let str = "foo bar 12 seconds 3minutes 4h";
let result = str.match(/(\d+) ?(?:sec|seconds) ?(\d+) ?(?:min|minutes) ?(\d+) ?(?:h|hours?)/);
console.log(`${result[3]}hour ${result[1]}second ${result[2]}minutes`);  

使用普通正则表达式没有简单的解决方案。最简单的解决方案是使用exec方法并将值设置为hash对象。此外,你可以简化你的正则表达式-所有的inute,其次,我们的在你的正则表达式中是完全无用的。如果只需要s或s,则应使用?:s | s,因为在您的示例中,5个样本也会匹配

在不处理设备顺序的情况下,最简单的问题解决方案是:

var str=foo bar 12秒5米4小时; 变量re=/\d+\s*[smh]/gi var hash={}; var-m; 而m=re.execstr!==空的{ //获取价值 var值=m[1]; var单位=m[2],小写; //设定值 散列[单位]=值; }
console.loghash 正如Wiktor正确指出的那样,用一个正则表达式无法做到这一点。下面是一个实现3-regex解决方案的简单函数:

函数get\u time\u partstext{ var s,m,h; //秒部分:秒、秒、秒或秒。 s=text.match/\b\d+\s*s?:ec?:ond?s???\b/i; s=s?s[1]:未定义; //分钟部分:m、min、min或min。 m=text.match/\b\d+\s*m?:in?:ute?s???\b/i; m=m?m[1]:未定义; //小时部分:小时、小时、小时或小时。 h=text.match/\b\d+\s*h?:rs?| ours???\b/i; h=h?h[1]:未定义; 返回s | m | h?[s,m,h]:null; } 如注释中所述,此功能允许以下时间段变化:

秒部分:秒、秒、秒或秒。 分钟部分:m、min、min或min。 小时部分:小时、小时、小时或小时


正则表达式不区分大小写,因此允许变化,例如HR、Sec、mIN等。如果不存在任何部分,函数将返回null

不,没有这样的方法,最干净的方法是运行3个单独的正则表达式,并按照您想要的方式安排匹配。同意@WiktorStribiżew。12秒和12秒之间的间隔有效吗?我这样问是因为秒、分钟和小时的格式看起来不同space@JBone是的,它是有效的。这些字符串由用户编写。有些人使用空间,有些人不使用。所以正则表达式说明了这一点。这个解决方案与@Marian发布的正则表达式不一样-如果你删除其中一个时间单位,你的正则表达式将不起作用。例如,字符串foo bar 12a seconds 5m 4h将强制执行错误。是的,这将简化我的正则表达式,tho s?:econds??或者?:s |秒仍将匹配5个样本,因为它以s开头。但不管怎样,这都有帮助。非常感谢。