简体   繁体   中英

regex to only allow an input to 3 decimal places with 0.001 being the smallest number possible, not 0

I am trying to write a regex to allow a user enter a positive number and to 3 decimal places. My regex looks like this, however, it isn't working as I would like.

/\d*[1-9](\.\d{0,3})?/

This allows the user to enter 1.000 as the smallest number, however, it doesn't allow a user to enter 0.001 which should be the smallest number possible to enter into the input.

Does anyone know what the regex should be to solve this?

Personally I would just check for 0 and make the regex a lot simpler, but here is a solution, where the required decimal places can be adjusted by changing {1,3}.

The jist of this regex is that we allow any number greater than two digits , then allow only 1-9 for one digit, then optionally require up to 1 decimal with 1-3 digits afterwards.

 const r = /^((([0-9]{2,}){1}|[1-9]{1})(\\.[0-9]{1,3}){0,1})$/; const tests = ['1','2','0','1.001','1.001.1','999.001','9.01','9.0100','abc']; tests.forEach(t=>console.log(t,r.test(t))); 

Your code has another issue where it can not match 10 since you are not allowing the ones place to be 0.

You need to use some or statements

 const re = /(^([1-9]|\\d{2,})(\\.\\d{0,3})?|0\\.\\d{0,2}[1-9])$/ const tests = ["0.001", "0.1", "0","0.0", "0.000","10.001", "10","11","1"] tests.forEach(n => console.log(n, re.test(n))) 

 const re = /^(?!0+(?:\\.0+)?$)\\d+(?:\\.\\d+)?$/ const tests = ["0.001", "0.1", "0","0.0", "0.000","10.001", "10","11","1","1.22","1.222"] tests.forEach(n => console.log(n, re.test(n))) 

Explanation:

^               # beginning of string
  (?!           # negative lookahead, make sure we haven't after:
    0+          # 1 or more zero
    (?:         # start non capture group
      \.        # a dot
      0+        # 1 or more zero
    )?          # end group, optional
    $           # end of string
  )             # end lookahead
  \d+           # 1 or more digits
  (?:           # start non capture group
    \.          # a dot
    \d+         # 1 or more digits
  )?            # end group, optionnal
$               # end of string

Another option is to use a negative lookahead to assert from the start of the string what is on the right is neither a dot or zero repeated until the end of the string:

^(?![0.]+$)\d+(?:\.\d{1,3})?$

See a Regex demo

Explanation

  • ^ Start of the string
  • (?![0.]+$) Negative lookahead to assert what is on the right is not what is listed in the character class repeated 1+ times until the end of the string
  • \\d+ Match 1+ times a digit
  • (?:\\.\\d{1,3})? Optional non capturing group which matches a dot and 1+ times a digit
  • $ End of the string

 const tests = ["0.001", "0.1", "0","0.0", "0.000","10.001", "10","11","1","1.22","1.222"] tests.forEach(n => console.log(parseFloat(n) >= 0.001)) 

I really think this is being overthought.

The answer is here.

([1-9]\.[0-9][0-9][0-9]|[0]\.[1-9][0-9][0-9]|[0]\.[0][1-9][0-9]|[0]\.[0][0][1-9])

This should match 0.001~9.999

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM