<?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)));
preferences:
25.27 ms | 406 KiB | 5 Q