时间字符串到秒

时间:2018-03-21 17:56:23

标签: php regex

如何用正则表达式解析字符串以计算总秒数? 字符串将在示例中:

40s
11m1s
1h47m3s

我从以下正则表达式开始

((\d+)h)((\d+)m)((\d+)s)

但是这个正则表达式只会匹配最后一个例子。 如何使部件可选? 是否有更好的正则表达式?

3 个答案:

答案 0 :(得分:2)

您使用的格式与java.time.Duration使用的格式非常相似:

https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-

也许你可以使用它而不是写自定义的东西?

持续时间使用如下格式:

P1H47M3S

也许你可以添加领先" P"并解析它(不确定你是否必须大写)?

格式称为" ISO-8601":

https://en.wikipedia.org/wiki/ISO_8601

例如,

$set = array(
    '40s',
    '11m1s',
    '1h47m3s'
);

$date = new DateTime();
$date2 = new DateTime();

foreach ($set as $value) {
  $date2->add(new DateInterval('PT'.strtoupper($value)));
}

echo $date2->getTimestamp() - $date->getTimestamp(); // 7124 = 1hour 58mins 44secs.

答案 1 :(得分:1)

您可以为每个(\dh\dm\ds使用可选的非捕获组:

$strs = ['40s', '11m1s', '1h47m3s'];

foreach ($strs as $str) {
    if (preg_match('~(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?~', $str, $matches)) {
        print_r($matches);
    }
}

输出:

Array
(
    [0] => 40s
    [1] =>     // h
    [2] =>     // m
    [3] => 40  // s
)
Array
(
    [0] => 11m1s
    [1] =>     // h
    [2] => 11  // m
    [3] => 1   // s
)
Array
(
    [0] => 1h47m3s
    [1] => 1   // h
    [2] => 47  // m
    [3] => 3   // s
)

正则表达式:

(?:     # non-capture group 1
  (     # capture group 1
   \d+  # 1 or more number
  )     # end capture group1
  h     # letter 'h'
)       # end non-capture group 1
?       # optional

(?:     # non-capture group 2
  (     # capture group 2
  \d+   # 1 or more number
  )     # end capture group1
  m     # letter 'm'
)       # end non-capture group 2
?       # optional

(?:     # non-capture group 3
  (     # capture group 3
  \d+   # 1 or more number
  )     # end capture group1
  s     # letter 's'
)       # end non-capture group 3
?       # optional

答案 2 :(得分:0)

这个表达式:

/(\d*?)s|(\d*?)m(\d*?)s|(\d*?)h(\d*?)m(\d*?)s/gm

返回3个匹配项,每行一个。每个匹配被分成仅有数字的突出组。

要点是,这将匹配任何数字之前的任何数字位数'或者在“&m;”之前加上任意数字的数字。或者在' h'之前加上任意数字的数字。