Regex That Matches a Number With Commas for Every Three Digits

How would you write a regex that matches a number with commas for every three digits?

Try this:

^(\d{1,3})(,\d{3})*$

https://regex101.com/r/Dy83Jv/1

regex ^ and $ are not working

prithvi,

your first regex works, actually.

Try this test:

import re

REGEX = re.compile("((^\d{1,3})((\,\d{3})*$))")

for test in ('42', '1,234', '6,368,745', '12,34,567', '1234'):
print(test, REGEX.match(test) != None)

The output is (python 3)

42 True
1,234 True
6,368,745 True
12,34,567 False
1234 False

UPDATE

prithvi asked in the comment about a regex that could be used in the findall method. Since the answer is a bit lengthy I put it here.

For findall the regex should have boundaries, that match something that is not a part of the number.

I suppose, the boundary before the match is either string beginning or a string that is neither digit nor comma. I encode such boundary as (?:^|(?<=[^0-9,]))

Same with the boundary after - it is either end of string or something that is neither digit nor comma: (?:(?=[^0-9,])|$)

How those regex are built.

  • ?: designates a group that is not included in the group list. I use for cleaner math result
  • ?<=[^0-9,] is a a positive lookbehind assertion. It means, that the following regex matches if and only if it is preceded by something that matches [^0-9,] (that is neither a digit nor a comma)
  • ?=[^0-9,] is a lookbehind assertion. It means, that the preceding part of regex matches if and only if it is followed by something that matches [^0-9,] (that is neither a digit nor a comma)

Here is an example:

REGEX = re.compile("(?:^|(?<=[^0-9,]))(\d{1,3}(?:\,\d{3})*)(?:(?=[^0-9,])|$)")
long_str = '42 1,234 6,368,745 12,34,567 1234'
print(REGEX.findall(long_str))

The result is ['1,234', '42', '6,368,745']

How to add a comma after every three digits?

There are different ways to skin this cat, but the first one that suggests itself to me is to take the mod and div of the string length into 3, and use the mod (if any) to determine the length of the first segment before everything gets sliced evenly into threes:

>>> def three_commas(x):
... b, a = divmod(len(x), 3)
... return ",".join(([x[:a]] if a else []) + [x[a+3*i:a+3*i+3] for i in range(b)])
...
>>> three_commas("2000")
'2,000'
>>> three_commas("31415")
'31,415'
>>> three_commas("123456789")
'123,456,789'


Related Topics



Leave a reply



Submit