9

Currently i am using this regex to match for positive numbers with a single decimal point

/^\d+(\.\d+)?$/

But this doesn't allow commas. How can i modify this to allow zero or more commas before the decimal point?

Example :

  • 11,111.00 (should be allowed) I am okay with numbers having any number of comma's before decimal point.

EDIT:

Valid values

  • 111
  • 11,111
  • 11,111.0
  • 111111

The values can be entered with or without comma. The datatype of this field is SQL MONEY, so it will handle comma's.

Prayag Sagar
  • 651
  • 1
  • 8
  • 21
  • Like [`/^\d{1,3}(?:,\d{3})*(?:\.\d+)?$/`](https://regex101.com/r/oHVe7e/2)? Or [`/^(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/`](https://regex101.com/r/oHVe7e/1)? – Wiktor Stribiżew Oct 25 '16 at 08:02
  • Possible duplicate of [Regex for number with decimals and thousand separator](http://stackoverflow.com/questions/16148034/regex-for-number-with-decimals-and-thousand-separator) – Sebastian Proske Oct 25 '16 at 08:04
  • The solution in the above question does nort match `11111111111.55`. Prayag, do you need a common regex to match values like `55555.87` and `12,567.78`? Or is `/^\d{1,3}(,\d{3})*(\.\d+)?$/` enough? – Wiktor Stribiżew Oct 25 '16 at 08:06
  • [after edit] So, does it mean you need `^(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$`? – Wiktor Stribiżew Oct 25 '16 at 08:29

4 Answers4

4

need

/^(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/

See the regex demo

Details

  • ^ - start of string
  • (?:\d{1,3}(?:,\d{3})*|\d+) - Either of:
    • \d{1,3}(?:,\d{3})* - 1 to 3 digits followed with 0+ sequences of a , and 3 digits
    • | - or
    • \d+ - 1 or more digits
  • (?:\.\d+)? - an optional sequence of . and 1+ digits
  • $ - end of string.

var strs = [',,,,', '111', '11,111', '11,111.0', '111111'];
var re = /^(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$/;
for (var s of strs) {
  console.log(s + " => " + re.test(s));
}
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Don't know if it matters, but it doesn't allow, say `10,00,00,000` which is a valid grouping of digits for India. – VLAZ Oct 25 '16 at 08:36
  • @vlaz: In that case, [`{3}` should be changed to `+`](https://regex101.com/r/oHVe7e/4). – Wiktor Stribiżew Oct 25 '16 at 08:38
  • Tested it against [this dataset](https://regex101.com/r/Hwhz5i/1), by the way and it's otherwise really good. It's just the annoying groupings that (as usual) are annoying. – VLAZ Oct 25 '16 at 08:38
  • @vlaz Agreed with your point regarding Indian groupings. But i am not looking for Indian groupings in my regex[But yes, I am an Indian :)], its for the American numbering system. – Prayag Sagar Oct 25 '16 at 09:51
3

This is a very simple general solution, without any assumptions about how many digits are needed.

/^\d[\d,]*(\.\d+)?$/

[\d,] will match digits or commas.
You could make the regex more complicated if you really need it to be more specific.

Buh Buh
  • 7,443
  • 1
  • 34
  • 61
1

I would use this

^(?:\d{1,3}(,\d{3})*|\d+|\d{2}(?:,\d{2})*,\d{3})(?:\.\d+)?$

See demo and explanation

Thomas Ayoub
  • 29,063
  • 15
  • 95
  • 142
  • Preforms [pretty well|https://regex101.com/r/X40vBl/2]. Indian numbers again but they may or may not be a of concern. – VLAZ Oct 25 '16 at 08:43
  • how would `10,00,00,000` be valid @vlaz? – Thomas Ayoub Oct 25 '16 at 08:56
  • 1
    International support. It's a valid grouping of digits in India, for example - if a number is big, the grouping character is placed every _two_ digts, aside from the last group of digits. https://en.wikipedia.org/wiki/Indian_numbering_system – VLAZ Oct 25 '16 at 09:05
  • I've had to deal with internationalised formats, so I know how much of a pain it can be. As I said, though, this may or might not be a problem - depends on the use case. The format expected is already not "international-friendly" as it expects `,` to be the digit separator and `.` to be the decimal separator when those could be swapped or different symbols altogether depending on the locale. I still included the Indian numbers in my testing set as a bit of a curve ball. – VLAZ Oct 25 '16 at 09:46
0

This is pretty hard to read but I'll explain it

/^(?:\d+)(?:(?:\d+)|(?:(?:,\d+)?))+(?:\.\d+)?$/

All the ?: are just to explicitly say to the regex engine "Don't capture the following group matched by this paren).

The simplified version would be

/^(\d+)((\d+)|((,\d+)?))+(\.\d+)?$/

But it'd capture a lot of matching groups for no reason so I removed them

axelduch
  • 10,769
  • 2
  • 31
  • 50