如何使用Javascript将持续时间字符串解析为秒?

时间:2012-08-10 21:23:16

标签: javascript regex

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

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

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

关键组件是1)天,2)小时3)分钟,但可能并不总是包含某些组件。

我的攻击计划是使用.match和regex。只要我能得到单词的第一个字母,我就会知道前面的数字是什么,并且能够处理所有不同格式的单词(例如小时,小时,小时,小时)。但是,因为我正在为此学习正则表达式,所以它比我想象的要复杂得多。

非常感谢任何帮助或建议!

5 个答案:

答案 0 :(得分:14)

您的字符串中的天/小时/分钟的顺序是否得到保证?如果没有,可能更容易为每个单独的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;
}

答案 1 :(得分: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/。该函数容忍可变数量的空格,并且在数字和单位标签之间将采用逗号,空格或两者。它要求在单位之后使用空格或逗号(至少一个)。

答案 2 :(得分:1)

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

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

这至少需要dhm,但接受常见的缩写。

答案 3 :(得分: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来改变字符串,但逐个处理匹配。注意天数,小时数可以按任何顺序排列。

答案 4 :(得分: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;
};