You need to handle two possibilities (numbers without a decimal part and numbers without an integer part):
/\A-?(?:\d+(?:\.\d*)?|\.\d+)\z/
or make everything optional and provide at least one digit there:
/\A-?+(?=.??\d)\d*\.?\d*\z/
# ^ ^ ^ ^---- optional dot
# | | '---- optional char (non-greedy)
# | '---- lookahead assertion: means "this position is followed by"
# '---- optional "-" (possessive)
. - ?? , , , . ?. ( , "unknow char", , .)