<?php
$tests = [
'bar 3 m foo', // -
'5s 4m', // -
'5s 10mins 4 days', // -
'bass drop 2 d bare', // -
'2 3 m foo foo', // -
'1 222 4 d baz', // -
'5d 4h 3m 2s', // -
'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
];
/*
* Replaces (s|m|h|d|w|mon) with strtotime compatible abbreviations
*
* ps. (?&int) is there so it doesn't replace the 's' in 'months' etc.
*
* @param array $tests
* @return array
*/
function normalizeTimeSpec($tests) {
$reg1 = "/(?<int> (?:\G|(?!\n)) \s*\b \d{1,5} \s* )\K
(?<time> (?: s|m(on)?|h|d|w)\b )
/uix";
$array = [];
foreach($tests as $case){
$out = preg_replace_callback ($reg1,
function($matches){
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 $t;
}, $case);
$array[] = $out;
}
return $array;
}
/*
* Test whether given time string passes regex rules & match
* @param array $tests
* @return array
*/
function testTimeSpec($tests){
$finalArray = [];
$regex = <<<'REGEX'
/(?(DEFINE)
(?<int>
(\s*\b)?
(\d{1,5})?
(\s*)?
)
(?<timepart>
(?&int)
( s(ec(ond)?s?)?
| m(in(ute)?s?|onths?)?
| h(rs?|ours?)?
| d(ays?)?
| w(eeks?)?
)
\b
)
)
^(?<time>
(?:(?&timepart)(*SKIP).)+
)
(?<string>.+)$
/uix
REGEX;
foreach($tests as $case){
if(preg_match($regex, $case, $matches)){
$finalArray[] = $matches['time'].$matches['string'];
}
}
return $finalArray;
}
print_r(normalizeTimeSpec($tests));
print_r(testTimeSpec(normalizeTimeSpec($tests)));
- Output for 5.6.0 - 5.6.26, 7.0.0 - 7.0.20, 7.1.0 - 7.1.33, 7.2.17 - 7.2.33, 7.3.0 - 7.3.33, 7.4.0 - 7.4.33, 8.0.0 - 8.0.30, 8.1.0 - 8.1.33, 8.2.0 - 8.2.29, 8.3.0 - 8.3.26, 8.4.1 - 8.4.13
- Array
(
[0] => bar 3 m foo
[1] => 5sec 4min
[2] => 5sec 10mins 4 days
[3] => bass drop 2 d bare
[4] => 2 3 m foo foo
[5] => 1 222 4 d baz
[6] => 5day 4hour 3min 2sec
[7] => 2 day 3 min baz
[8] => 5day 4hour 3min 2sec foo
[9] => 2 sec foo
[10] => 222 hour baz bar
[11] => 1 month foo
[12] => 1week bar
[13] => 1 month baz
[14] => 2 months foobar
[15] => 4 months 2 months foo
)
Array
(
[0] => 2 day 3 min baz
[1] => 5day 4hour 3min 2sec foo
[2] => 2 sec foo
[3] => 222 hour baz bar
[4] => 1 month foo
[5] => 1week bar
[6] => 1 month baz
[7] => 2 months foobar
[8] => 4 months 2 months foo
)
preferences:
135.97 ms | 410 KiB | 5 Q