<?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);
- Output for 5.6.0 - 5.6.26, 7.0.0 - 7.0.20, 7.1.0 - 7.1.20, 7.2.6 - 7.2.33, 7.3.16 - 7.3.33, 7.4.0 - 7.4.33, 8.0.0 - 8.0.30, 8.1.0 - 8.1.30, 8.2.0 - 8.2.25, 8.3.0 - 8.3.13
- Array
(
[0] => Array
(
[0] => 2 day 3 min
[1] => baz
)
[1] => Array
(
[0] => 5 day 4 hour 3 min 2 sec
[1] => foo
)
[2] => Array
(
[0] => 2 sec
[1] => foo
)
[3] => Array
(
[0] => 222 hour
[1] => baz bar
)
[4] => Array
(
[0] => 1 month
[1] => foo
)
[5] => Array
(
[0] => 1 week
[1] => bar
)
[6] => Array
(
[0] => 1 month
[1] => baz
)
[7] => Array
(
[0] => 2 month
[1] => foobar
)
[8] => Array
(
[0] => 4 month 2 month
[1] => foo
)
[9] => Array
(
[0] => 5 min 3 sec
[1] => bar
)
[10] => Array
(
[0] => 7 month 6 week 5 day 4 hour 3 min 2 sec
[1] => bazinga!
)
[11] => Array
(
[0] => 3 sec 5 hour 5 min
[1] => jeeey hoe :D damn I should sleep...
)
)
preferences:
77.56 ms | 411 KiB | 5 Q