<?php
$tests = [
'bar 3 m foo', # -
'bass drop 2 d bare', # -
'2 3 m foo foo', # -
'1 222 4 d baz', # -
'5d 4h 3m 2s', # -
'5 days 4 minutes', # -
'9w8d7h6m5s', # -
'2 d 3 m baz', # +
'5d 4h 3m 2s foo', # +
'2 s foo', # +
'222 h baz bar', # +
'1 mon foo', # + mon for month?
'1w bar', # +
'1 month baz', # +
'2 months foobar', # +
'4 months 2 months foo', # + repeating same string is allowed by strtotime, though it sums up https://3v4l.org/FIgNC
'5m3s bar', # +
'7mon6w5d4h3m2s bazinga!', # +
'3 seconds 5 hours 5 minutes jeeey hoe :D damn I should sleep...' # +
];
/*
* Replaces (s|m|h|d|w|mon) with strtotime compatible abbreviations and return it in an array with the remaining text
*
* It *should* allow these: https://gist.github.com/DaveRandom/625fb4bf73112474fb5768a0a300e4e5
*
* @param array $tests
* @return array
*/
function separateAndNormalizeTimeSpec($tests) {
$reg1 = <<<'REGEX'
~
\s? (?<int> \d{1,5}) \s?
(?<time>
(?: s (?=(?:ec(?:ond)?s?)?(?:\b|\d))
| m (?=(?:in(?:ute)?s?)?(?:\b|\d))
| h (?=(?:(?:ou)?rs?)?(?:\b|\d))
| d (?=(?:ays?)?(?:\b|\d))
| w (?=(?:eeks?)?(?:\b|\d))
| mon (?=(?:(?:th)?s?)?(?:\b|\d))
)
)
[^\d]*?(?=\b|\d)
# do only extract start of string
| (?<text> .+)
~uix
REGEX;
$array = [];
foreach($tests as $case){
$text = "";
$time = preg_replace_callback ($reg1,
function($matches) use (&$text) {
if (isset($matches['text'])) {
$text = trim($matches['text']);
return '';
}
switch($matches['time']){
case 's':
$t = ' sec ';
break;
case 'm':
$t = ' min ';
break;
case 'h':
$t = ' hour ';
break;
case 'd':
$t = ' day ';
break;
case 'w':
$t = ' week ';
break;
case 'mon':
$t = ' month ';
break;
}
return $matches['int'].$t;
}, $case);
if ($time != "" && $text != "") {
$array[] = [$time, $text];
}
}
return $array;
}
$normalized = separateAndNormalizeTimeSpec($tests);
print_r($normalized);
preferences:
69.39 ms | 406 KiB | 5 Q