Reputation: 73253
I need to replace a number with a decimal point with a colon. So in short:
Pick me up at 5.50 and take me to the zoo
Pick me up at 5:50 and take me to the zoo
However, I don't want to replace a number with just a period:
Pick me up at 5. Take me to the zoo.
Pick me up at 5. Take me to the zoo.
I could do this by brute force, but I believe a regex is the best solution here, and inevitably as I am not a regex expert, I have come up against Zawinski's Law.
I can match the number, but I am stuck on how to do the replacement.
\d\.\d+
I believe I need to use lookahead and/or grouping, but I'm not familiar with the syntax.
I've found previous questions like Replace dot(.) with comma(,) using RegEx? and Remove decimal point when not between two digits but the first advises not using a regex at all, while the second seems relevant but I can't figure out how to change the answer to get the match, let alone how to replace it.
Upvotes: 3
Views: 2556
Reputation: 626950
To continue with your current solution, you need to make sure the digits on both ends of the dot can be left intact after the replacement, but still be accounted (checked) for when matching.
There are 2 ways to achieve that:
Here is the first approach with capturing groups:
Regex.Replace(s, @"(\d)\.(\d+)", "$1:$2")
And the other with lookarounds:
Regex.Replace(s, @"(?<=\d)\.(?=\d)", ":")
See the regex demo 1 and regex demo 2.
Details
(\d)
- Group 1 (later referred to with the help of the $1
replacement backreference): any one Unicode digit or(?<=\d)
- a positive lookbehind that requires a digit immediately to the left of the current location\.
- a dot(\d+)
- Group 2 (later referred to with the help of the $2
replacement backreference): any 1 or more Unicode digits or(?=\d)
- a positive lookahead that requires a digit immediately to the right of the current locationYou might go on tweaking it to only match the strings inside word boundaries with a limiting quantifier on the second \d
to match only 2 digits:
\b(\d)\.(\d{2})\b
or
(?<=\b\d)\.(?=\d{2}\b)
See another regex demo (and Version 2 regex with lookarounds). Note that sometimes further word boundary adjustment is necessary.
To make sure you only match ASCII digits, use the RegexOptions.ECMAScript
option. Or replace all \d
with [0-9]
.
Upvotes: 4
Reputation: 3197
For 24h format, you could use this regex:
/([0-1]?[0-9]|[2][0-3]).[0-5]?[0-9]/
Basically this matches:
Hours:
Minutes:
To make sure you do it only when the valid time is entered. It's closest you can get. Match entire regex, replace .
with :
and put it back.
Upvotes: 1