Reputation: 63
I need to match regex to value that is numeric with decimal. Currently I have /^-?[0-9]\d*(.\d+)/ but it does not account for .00 How would I fix that
Current Valid:
1
1.0
1.33
.00
Current Invalid:
Alpha Character
Upvotes: 5
Views: 3975
Reputation: 110755
Here's a different approach.
def match_it(str)
str if str.gsub(/[\d\.-]/, '').empty? && Float(str) rescue nil
end
match_it "1" #=> "1"
match_it "1.0" #=> "1.0"
match_it "-1.0" #=> "-1.0"
match_it "1.33" #=> "1.33"
match_it ".00" #=> ".00"
match_it "-.00" #=> "-.00"
match_it "1.1e3" #=> nil
match_it "Hi!" #=> nil
Upvotes: 0
Reputation: 99061
Create a regex with the variants you want to match, in this case, 3:
N
N.NN
.NN
i.e.:
(\d+\.\d+|\d+|\.\d+)
Upvotes: 1
Reputation: 130
I would use something like ^\-?[0-9\.]+
or (^\-?[0-9\.]+)
, if you want to capture that specific part of the line only. This looks for any combination of the digits 0
through 9
and a decimal point (.
), at the beginning of a line with the option of it starting with a dash (-
).
I also highly recommend the website Rubular as a great place to test and play with regexes.
Upvotes: 0
Reputation: 89639
You need to handle the two possibilities (numbers without a decimal part and numbers without an integer part):
/\A-?(?:\d+(?:\.\d*)?|\.\d+)\z/
#^ ^ ^ ^^ ^---- end of the string
#| | | |'---- without integer part
#| | | '---- OR
#| | '---- with an optional decimal part
#| '---- non-capturing group
#'---- start of the string
or make all optional and ensure there's at least one digit:
/\A-?+(?=.??\d)\d*\.?\d*\z/
# ^ ^ ^ ^---- optional dot
# | | '---- optional char (non-greedy)
# | '---- lookahead assertion: means "this position is followed by"
# '---- optional "-" (possessive)
Note: I used the non-greedy quantifier ??
only because I believe that numbers with integer part are more frequent, but it can be a false assumption. In this case change it to a greedy quantifier ?
. (whatever the kind of quantifier you use for the "unknow char" it doesn't matter, this will not change the result.)
Upvotes: 6
Reputation: 211740
If the first part is optional you can mark it off as such with `(?:...)?:
/\A(?:-?[0-9]\d*)?(.\d+)/
The ?:
beginning means this is a non-capturing group so it won't interfere with the part you're trying to snag.
Upvotes: 1