We are using a preg_replace to get a well formated time string. The result should look like this:
mo-sa9:00-20:00uhr
=> mo-sa 09:00-20:00uhr
The regex is:
preg_replace('=[^\d](\d{1})[.:](\d{2})=U', ' 0${1}:${2}', $norm)
The result is: mo-s 09:00-20:00uhr
After many attempts, I found that I couldn't seem to find a pattern that correctly formatted the time string.
The replacement seems to be the problem or am I looking at it wrong?
CodePudding user response:
You can use
preg_replace('~(?<!\d)(\d)[.:](\d{2})~', ' $1:$2', $norm)
Or, if you want to keep the separator char:
preg_replace('~(?<!\d)(\d)([.:])(\d{2})~', ' $1$2$3', $norm)
See the regex demo. Details:
(?<!\d)
- a left-hand digit boundary(\d)
- Group 1 ($1
): a digit([.:])
- Group 2 ($2
):.
or:
(\d{2})
- Group 3 ($3
): two digits.
See the PHP demo:
<?php
$norm = 'mo-sa9:00-20:00uhr';
echo preg_replace('~(?<!\d)(\d)([.:])(\d{2})~', ' $1$2$3', $norm);
// => mo-sa 9:00-20:00uhr
CodePudding user response:
The current issue is that [^\d]
is matching the a
but you do nothing with it so it is lost on replacing.
I would use preg_replace_callback
and use datetime functions to ensure leading zeros as needed.
echo preg_replace_callback('/(\d\d?:\d\d)-(\d\d?:\d\d)/', function($match){
return ' ' . date('H:i', strtotime($match[1])) . '-' . date('H:i', strtotime($match[2]));
}, 'mo-sa9:00-20:00uhr');
CodePudding user response:
You can match the part that you want, and assert what should be to the right as well.
Note that you can omit {1}
, you can write [^\d]
as \D
and you don't need the /U
flag to make quantifiers lazy.
\D\K(?=\d[.:]\d{2}\b)
Explanation
\D
Match a non digit and then a single digit\K
Forget what is matched so far(?=
Positive lookahead to assert what is to the right\d[.:]\d{2}
Match a digit, then either.
or:
and 2 digits\b
A word boundary to prevent a partial word match
)
Close the lookahead
In the replacement use 0
$re = '/\D\K(?=\d[.:]\d{2}\b)/';
$norm = 'mo-sa9:00-20:00uhr';
echo preg_replace($re, " 0", $norm);
Output
mo-sa 09:00-20:00uhr
If the string is always formatted like this, you could also opt for a precise match:
\b[a-z] -[a-z] \K\d:\d\d-\d\d:\d\duhr\b
In the replacement use the 2 capture groups with a space in between.
$re = '/\b[a-z] -[a-z] \K\d:\d\d-\d\d:\d\duhr\b/';
$norm = 'mo-sa9:00-20:00uhr';
echo preg_replace($re, " 0$0", $norm); // mo-sa 09:00-20:00uhr