9

我正在尝试使用 Javascript 解析用户输入字符串的持续时间(以秒为单位)。

以下是我希望能够处理的一些示例输入:

  • “1小时2分钟”
  • “1天2小时3分钟”
  • “1d 2h 37m”
  • “1天2分钟”
  • “3天20小时”

关键组成部分是 1) 天,2) 小时 3) 分钟,但某些组成部分可能并不总是包括在内。

我的攻击计划是使用 .match 和正则表达式。只要我能得到单词的第一个字母,我就会知道前面的数字是什么,并且能够处理单词的所有不同格式(例如 hours、hour、hr、h)。然而,由于我正在为此学习正则表达式,结果证明它比我想象的要复杂得多。

任何帮助或建议将不胜感激!

4

5 回答 5

15

您的字符串中的天/小时/分钟的顺序是否得到保证?如果没有,为每个单独的 RegEx 做一个单独的 RegEx 可能会更容易。像这样的东西?

function getSeconds(str) {
  var seconds = 0;
  var days = str.match(/(\d+)\s*d/);
  var hours = str.match(/(\d+)\s*h/);
  var minutes = str.match(/(\d+)\s*m/);
  if (days) { seconds += parseInt(days[1])*86400; }
  if (hours) { seconds += parseInt(hours[1])*3600; }
  if (minutes) { seconds += parseInt(minutes[1])*60; }
  return seconds;
}
于 2012-08-10T21:36:46.503 回答
2

您可以使用此代码将您的字符串分解为一个数字,后跟一个单位字符串:

function getPieces(str) {
    var pieces = [];
    var re = /(\d+)[\s,]*([a-zA-Z]+)/g, matches;
    while (matches = re.exec(str)) {
        pieces.push(+matches[1]);
        pieces.push(matches[2]);
    }
    return(pieces);
}

然后函数返回一个数组,例如数组["1","day","2","hours","3","minutes"]中的交替项是值,然后是该值的单位。

所以,对于字符串:

"1 day, 2 hours, 3 minutes"

函数返回:

[1, "day", 2, "hours", 3, "minutes"]

然后,您可以检查每个值的单位以决定如何处理它。

在这里工作演示和测试用例:http: //jsfiddle.net/jfriend00/kT9qn/。该函数可以容忍可变数量的空格,并且在数字和单位标签之间使用逗号、空格或两者都不使用。它期望在单元之后有一个空格或一个逗号(至少一个)。

于 2012-08-10T21:48:37.190 回答
1

您可以在正则表达式中使用可选子字符串来匹配您描述的任何组合:

/(\d+)\s*d(ays?)?\s*(\d+)\s*h(ours?)?\s*(\d+)\s*m(in(utes?)?)?/

这至少需要一个d, h, 并且m接受常见的缩写。

于 2012-08-10T21:28:21.800 回答
1
var str = "1 day, 2 hours, 3 minutes";

var seconds = 0;
str.replace (/\s*,?(\d+)\s*(?:(d)(?:ays?)?|(h)(?:ours?)?|(m)(?:in(?:utes?)?)?)/g, function (m0, n, d, h, m) {
  seconds += +n * (d ? 24 * 60 * 60 : h ? 60 * 60 : 60);
  return m0; 
});

在这里,我使用 replace 不是更改字符串,而是一一处理匹配项。注意天、小​​时/分钟可以按任何顺序排列。

于 2012-08-10T22:08:13.707 回答
0

接受的答案的更通用版本,也接受月和秒。

const getSeconds = str => {
    let seconds = 0;
    let months = str.match(/(\d+)\s*M/);
    let days = str.match(/(\d+)\s*D/);
    let hours = str.match(/(\d+)\s*h/);
    let minutes = str.match(/(\d+)\s*m/);
    let secs = str.match(/(\d+)\s*s/);
    if (months) { seconds += parseInt(months[1])*86400*30; }
    if (days) { seconds += parseInt(days[1])*86400; }
    if (hours) { seconds += parseInt(hours[1])*3600; }
    if (minutes) { seconds += parseInt(minutes[1])*60; }
    if (secs) { seconds += parseInt(secs[1]); }
    return seconds;
};

于 2019-02-27T03:20:18.500 回答