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
\DMatch a non digit and then a single digit\KForget 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\bA 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
