cblnpa
cblnpa

Reputation: 517

Regex expression for numbers and leading zeros just with a dot and decimal

I'm trying to find a regex for numeric inputs. We can receive a leading 0 just if we add a dot for adding 1 or 2 decimal numbers. And of course just accept numbers.

These are the scenarios that we can accept:

0.01 
1.1
1.02
120.01

We can't accept these values

0023
0100
.01
.12

Which regex is the best option for these cases?

Until now we try we the following regex for accepting just number and dots

[A-Za-z,]

And also we try with the following ones:

^[+-]?[0-9]{1,3}(?:[0-9]*(?:[.,][0-9]{1})?|(?:,[0-9]{3})*(?:\.[0-9]{1,2})?|(?:\.[0-9]{3})*(?:,[0-9]{1,2})?)$

"/^[-]?[$]\d{1,3}(?:,?\d{3})*\.\d{2}$/"

"/(^(\d{1})\.{0,1}([0-9]){0,2}$)|(^([1-9])\d{0,2}(\,\d{0,3})$)/g"

(?:0|[1-9][0-9]*)(?:\.[0-9]{1,2})?

And the next one for deleting the leading zeros but it didn't work for 0.10 cases

^0+

Upvotes: 1

Views: 3006

Answers (3)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626748

You can use

^(?![0.]+$)(?:[1-9]\d*|0)(?:\.\d{1,2})?$

See the regex demo.

Details:

  • ^ - start of string
  • (?![0.]+$) - fail the match if there are just zeros or dots till end of string
  • (?:[1-9]\d*|0) - either a non-zero digit followed with any zero or more digits or a zero
  • (?:\.\d{1,2})? - optionally followed with a sequence of a . and one or two digits
  • $ - end of string.

Upvotes: 0

Patrick Janser
Patrick Janser

Reputation: 4244

I would go with ^(0|[1-9]\d*|(0|[1-9]\d*)\.\d+)$

You can test here: https://regex101.com/r/oNMgR9/1

Explanation

  • ^ means : match the beginning of the string (or line if the m flag is enabled).
  • $ means : match the end of the string (or line if the m flag is enabled).
  • (a|b) means match "a" or match "b" so I'll use this to match either "0" alone or any number not starting with a "0". It's the syntax for a logical or.
  • . alone is used to match any char. So you have to escape it if you want to match the dot character. This is why I wrote 0\. instead of 0..
  • [ ] is used to list some characters you want to match. It can be a range if you use the - char, so [1-9] means any digit char from "1" to "9".
  • \d is to match a digit. It's totally equivalent to [0-9].
  • * means : match the preceding pattern 0 or many times, so \d* means that it will match 0 or many times a digit, so it will match "8" or "465" or "09" but also an empty string "". If you want to match the preceding pattern at least once or many times then you use + instead of *. So \d+ won't match an empty string "" but \d* would match it.

A) Just a number not starting with 0

[1-9]\d* will match any digit from 1 to 9 and then optionnaly followed by other digits. This will match numbers without a decimal point.

B) Just 0

0 alone is a possibility. This is because the case above isn't covering it.

B) A number with decimals

(0|[1-9]\d*)\.\d+ will match either a "0" alone or a number not starting by "0" and then followed by a point and some other digits (which have to be present because we don't want to match "45." without the numbers behind the dot).

Better alternative

The solution from @TheFourthBird is a bit cleaner with the use of a negative lookahead. It's just a bit different to understand. And he read the question completely: You wanted 1 or 2 digits after the decimal. I forgot about that, so, effectively, \d+ should be replaced by \d{1,2} as you don't want more than 2 digits.

Upvotes: 1

The fourth bird
The fourth bird

Reputation: 163237

If a negative lookahead is supported, you can exclude matches that start with a zero and have no decimal part.

^(?!0\d*$)\d+(?:\.\d{1,2})?$
  • ^ Start of string
  • (?!0+\d*$) Negative lookahead, assert not a zero followed by optional digits at the right
  • \d+ Match 1+ digits
  • (?:\.\d{1,2})? Match an optional decimal part with 1 or 2 digits
  • $ End of string

Regex demo

Upvotes: 3

Related Questions