Python regex for number with or without decimals using a dot or comma as separator?
You need to make [.,]
part as optional by adding ?
after that character class and also don't forget to add anchors. ^
asserts that we are at the start and $
asserts that we are at the end.
^\d*[.,]?\d*$
DEMO
>>> import re
>>> r = re.compile(r"^\d*[.,]?\d*$")
>>> if r.match('0.1.'): print 'it matches!'
...
>>> if r.match('0.abc'): print 'it matches!'
...
>>> if r.match('0.'): print 'it matches!'
...
it matches!
If you don't want to allow a single comma or dot then use a lookahead.
^(?=.*?\d)\d*[.,]?\d*$
DEMO
The problem is that you are asking for a partial match, as long as it starts at the beginning.
One way around this is to end the regex in \Z
(optionally $
).
\Z
Matches only at the end of the string.
and the other is to use re.fullmatch
instead.
import re
help(re.match)
#>>> Help on function match in module re:
#>>>
#>>> match(pattern, string, flags=0)
#>>> Try to apply the pattern at the start of the string, returning
#>>> a match object, or None if no match was found.
#>>>
vs
import re
help(re.fullmatch)
#>>> Help on function fullmatch in module re:
#>>>
#>>> fullmatch(pattern, string, flags=0)
#>>> Try to apply the pattern to all of the string, returning
#>>> a match object, or None if no match was found.
#>>>
Note that fullmatch
is new in 3.4.
You should also make the [.,]
part optional, so append a ?
to that.
'?'
Causes the resulting RE to match 0 or 1 repetitions of the preceding RE. ab? will match either ‘a’ or ‘ab’.
Eg.
import re
r = re.compile("[0-9]*[.,]?[0-9]*\Z")
bool(r.match('0.1.'))
#>>> False
bool(r.match('0.abc'))
#>>> False
bool(r.match('0123'))
#>>> True
Your regex would work fine if you just add the ^ at the front and the $ at the back so that system knows how your string would begin and end.
Try this
^[0-9]*[.,]{0,1}[0-9]*$
import re
checklist = ['1', '123', '123.', '123.4', '123.456', '.456', '123,', '123,4', '123,456', ',456', '0.,1', '0a,1', '0..1', '1.1.2', '100,000.99', '100.000,99', '0.1.', '0.abc']
pat = re.compile(r'^[0-9]*[.,]{0,1}[0-9]*$')
for c in checklist:
if pat.match(c):
print '%s : it matches' % (c)
else:
print '%s : it does not match' % (c)
1 : it matches
123 : it matches
123. : it matches
123.4 : it matches
123.456 : it matches
.456 : it matches
123, : it matches
123,4 : it matches
123,456 : it matches
,456 : it matches
0.,1 : it does not match
0a,1 : it does not match
0..1 : it does not match
1.1.2 : it does not match
100,000.99 : it does not match
100.000,99 : it does not match
0.1. : it does not match
0.abc : it does not match