Reputation: 4336
I have the following Ruby flavoured regex:
data.to_s.match(/\A[[:digit:]]*+((.|,)[[:digit:]]+)?\Z/) ? true : false
This returns true for the following examples as intended:
data = "13"
data = "1,3"
data = "13,3"
data = "1.3"
data = ",3"
data = ".3"
What is not clear to me is why the asterix after the first [[:digit:]] also allows a character to be passed at the beginning of the string:
irb > "a3".match(/\A[[:digit:]]*+((.|,)[[:digit:]]+)?\Z/)
=> #<MatchData "a3" 1:"a3" 2:"a">
How can I have it only match digits?
Upvotes: 1
Views: 90
Reputation: 20408
.
is a regexp metachar that matches any character (except newline) you need to escape it in your alternation:
data.to_s.match(/\A[[:digit:]]*((\.|,)[[:digit:]]+)?\Z/) ? true : false
# this dot needs escaping ^
Also the +
after the first *
is redundant (one or more repetitions of zero or more digits). Also ruby has a shorter friendly way to say [[:digit:]]
: \d
. Since this is a whole string match, do you really want to allow \n
at end of string? If not, use \z
over \Z
data.to_s.match(/\A\d*((\.|,)\d+)?\z/) ? true : false
Upvotes: 3
Reputation: 53319
The .
in your regex is matching any character and needs to be escaped as \.
:
data.to_s.match(/\A[[:digit:]]*+((\.|,)[[:digit:]]+)?\Z/) ? true : false
Upvotes: 1