'How to make regex that matches a number with commas for every three digits?

I am a beginner in Python and in regular expressions and now I try to deal with one exercise, that sound like that:

How would you write a regex that matches a number with commas for every three digits? It must match the following:

'42'

'1,234'

'6,368,745'

but not the following:

'12,34,567' (which has only two digits between the commas)

'1234' (which lacks commas)

I thought it would be easy, but I've already spent several hours and still don't have write answer. And even the answer, that was in book with this exercise, doesn't work at all (the pattern in the book is ^\d{1,3}(,\d{3})*$)

Thank you in advance!



Solution 1:[1]

The answer in your book seems correct for me. It works on the test cases you have given also.

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

The '^' symbol tells to search for integers at the start of the line. d{1,3} tells that there should be at least one integer but not more than 3 so ;

1234,123 

will not work.

(,\d{3})*$

This expression tells that there should be one comma followed by three integers at the end of the line as many as there are.

Maybe the answer you are looking for is this:

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

Which matches a number with commas for every three digits without limiting the number being larger than 3 digits long before the comma.

Solution 2:[2]

You can go with this (which is a slightly improved version of what the book specifies):

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

Demo on Regex101

Solution 3:[3]

I got it to work by putting the stuff between the carrot and the dollar in parentheses like so: re.compile(r'^(\d{1,3}(,\d{3})*)$') but I find this regex pretty useless, because you can't use it to find these numbers in a document because the string has to begin and end with the exact phrase.

Solution 4:[4]

#This program is to validate the regular expression for this scenerio. 
#Any properly formattes number (w/Commas) will match.
#Parsing through a document for this regex is beyond my capability at this time.

print('Type a number with commas')
sentence = input() 

import re

pattern = re.compile(r'\d{1,3}(,\d{3})*')

matches = pattern.match(sentence)
if matches.group(0) != sentence:
    #Checks to see if the input value
    #does NOT match the pattern.
    print ('Does Not Match the Regular Expression!')

else:
    print(matches.group(0)+ ' matches the pattern.')
    #If the values match it will state verification.

Solution 5:[5]

The Simple answer is :

^\d{1,2}(,\d{3})*$   
^\d{1,2} - should start with a number and matches 1 or 2 digits.    
(,\d{3})*$ - once ',' is passed it requires 3 digits.

Works for all the scenarios in the book. test your scenarios on https://pythex.org/

Solution 6:[6]

I also went down the rabbit hole trying to write a regex that is a solution to the question in the book. The question in the book does not assume that each line is such a number, that is, there might be multiple such numbers in the same line and there might some kind of quotation marks around the number (similar to the question text). On the other hand, the solution provided in the book makes those assumptions: (^\d{1,3}(,\d{3})*$)

I tried to use the question text as input and ended up with the following pattern, which is way too complicated:

r'''(
    (?:(?<=\s)|(?<=[\'"])|(?<=^)) 
    \d{1,3}
    (?:,\d{3})*
    (?:(?=\s)|(?=[\'"])|(?=$))
    )'''
  • (?:(?<=\s)|(?<=[\'"])|(?<=^)) is a non-capturing group that allows the number to start after \s characters, ', ", or the start of the text.
  • (?:,\d{3})* is a non-capturing group to avoid capturing, for example, 123 in 12,123.
  • (?:(?=\s)|(?=[\'"])|(?=$)) is a non-capturing group that allows the number to end before \s characters, ', ", or the end of the text (no newline case).

Obviously you could extend the list of allowed characters around the number.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 mahendra kamble
Solution 2 Sebastian Lenartowicz
Solution 3 henTri
Solution 4 Seth
Solution 5 sandeep kumar
Solution 6 oldblackjoe21