Reputation: 75
I need to read numbers from a string in the format
{any number of digits} {period} {two digits}
Example:
256.23 = 256.23
231.1 = false
2321 = false
das2312.23 = false
However, the problem is that in this string there are dates sometimes and I would like to achieve the following effect:
20.10.20 = false
23.12 = 23.12
I currently have a ReGex like this:
(\d+\.\d{2})
but this return like this:
29.74.23 = 29.74
I also tried:
(\d+\.\d{2}(?!\.))
but it's return = 74.23.
@edit: PHP
Upvotes: 0
Views: 50
Reputation: 31354
If the language where you use this supports it, you would use a lookbehind and lookahead, so start with (?<=(?:\s|^))
and end with (?=(?:\s|$))
i.e. before the match there should be the start of the string, or a space, and similar at the end:
(?<=(?:\s|^))(\d+\.\d{2})(?=(?:\s|$))
Of course, if the number would always be the only thing in the string, you could just use:
^(\d+\.\d{2})$
(?<=(?:\s|^))
explained:
(?<=..)
is a lookbehind expression, meaning "check that this comes immediately before"(?:\s|^)
just means "match either whitespace or the start of the line" and thanks to the ?:
it doesn't become a numbered group.(?=(?:\s|$))
is similar, except that $
is the end of the line and it starts with ?=
, which means "check that this comes immediately after"
@thefourthbird correctly pointed out that you can avoid the non-capturing group in this case (since it's already in the lookbehind/lookahead parentheses):
(?<=\s|^)(\d+\.\d{2})(?=\s|$)
Upvotes: 1
Reputation: 2759
If you don't want surrounding digits or dots and disregarding surrounding dots:
(?<![.\d])\d+\.\d\d(?![\d.])
You can always add to the classes to disregard any other characters
not wanted.
But if you go that route, you'd likely need whitespace boundary's instead.
(?<!\S)\d+\.\d\d(?!\S)
which is much more potent.
Upvotes: 0