<?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
*
* It *should* allow these: https://gist.github.com/DaveRandom/625fb4bf73112474fb5768a0a300e4e5
*
* NOTE: Below regex...uh, specially the (?&str) bit probably sucks...
*
* @param array $tests
* @return array
*/
function normalizeTimeSpec($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
| .+ (*SKIP)
~uix
REGEX;
$array = [];
foreach($tests as $case){
$output = preg_replace_callback ($reg1,
function($matches){
if (!isset($matches['int'])) {
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);
$array[] = $output;
}
return $array;
}
/*
* Test whether given time string passes regex rules (and show the matches array)
* This is mainly for Reminders plugin where we allow trailing (but not leading) strings
*
* @param array $tests
* @return array
*/
function testTimeSpec($tests){
$finalArray = [];
# I saw another solution given by @bwoebi - https://3v4l.org/6BoW1
# However that doesn't fail any longer than "5 months 4 weeks" see ^
# pretty sure these can be improved (but it's late and I can't regex any more now...)
$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;
}
$normalized = normalizeTimeSpec($tests);
$output = testTimeSpec(normalizeTimeSpec($tests));
print_r($normalized);
print_r($output);
- Output for git.master, git.master_jit, rfc.property-hooks
- Array
(
[0] =>
[1] =>
[2] =>
[3] =>
[4] => 5 day 4 hour 3 min 2 sec
[5] => 5 day 4 min
[6] => 9 week 8 day 7 hour 6 min 5 sec
[7] => 2 day 3 min
[8] => 5 day 4 hour 3 min 2 sec
[9] => 2 sec
[10] => 222 hour
[11] => 1 month
[12] => 1 week
[13] => 1 month
[14] => 2 month
[15] => 4 month 2 month
[16] => 5 min 3 sec
[17] => 7 month 6 week 5 day 4 hour 3 min 2 sec
[18] => 3 sec 5 hour 5 min
)
Array
(
)
This tab shows result from various feature-branches currently under review by the php developers. Contact me to have additional branches featured.
Active branches
Archived branches
Once feature-branches are merged or declined, they are no longer available. Their functionality (when merged) can be viewed from the main output page
preferences:
56.72 ms | 402 KiB | 8 Q