0

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 wrote following python program in python 3. what am I doing wrong here? It gives AttributeError

import re
numRegx = re.compile(r"""^
(\d{1,3}(\,))? # optional first three digits and comma (1,)
((d{3})(\,))*  # optional Second three digits and comma (345,)
\d{3}$         # Last three digits (456)
""", re.VERBOSE)
mo = numRegx.search('1,345,456')
print(mo.group())
Maulik
  • 2,881
  • 1
  • 22
  • 27
  • 1
    `'42'` lacks commas as well, so why you want it? Also our regex doesn't match anything and returns None, that's why you're getting attribute error. – Mazdak Feb 17 '17 at 14:04
  • Yes. I see what's problem(comma is required in my code) with 42 but why does it not work with 1,345,456? @Kasramvd. – Maulik Feb 17 '17 at 14:07
  • re.VERBOSE will handle it @SiHa – Maulik Feb 17 '17 at 14:08
  • I think that's because of new-lines but still your regex is not correct. – Mazdak Feb 17 '17 at 14:10
  • @Kasramvd, re.VERBOSE also ignores new-lines. I tried it in single line also. – Maulik Feb 17 '17 at 14:11
  • 1
    In single line without comments it gives me `345,456`. – Mazdak Feb 17 '17 at 14:11
  • Also how you want to handle 42? – Mazdak Feb 17 '17 at 14:12
  • I would handle numbers with less than 4 digits using the last part with `{1,3}`. – languitar Feb 17 '17 at 14:13
  • http://www.diveintopython.net/regular_expressions/verbose.html From the link: Whitespace is ignored. Spaces, tabs, and carriage returns are not matched as spaces, tabs, and carriage returns. They're not matched at all. (If you want to match a space in a verbose regular expression, you'll need to escape it by putting a backslash in front of it.) why it make the differance @Kasramvd – Maulik Feb 17 '17 at 14:18
  • So what's you general strategy for matching numbers? please update your question with a comprehensive explanation. – Mazdak Feb 17 '17 at 14:22

3 Answers3

6

Try this:

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

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

Chalda Pnuzig
  • 406
  • 4
  • 16
2

This Should Work.

Regex:

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

JavaScript Code:

const regex = /^(?:\d{1,3}(?:,\d{3})*)$/gm;
const str = `42
1,234
6,368,745
12,34,567`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

Input:

42
1,234
6,368,745
12,34,567
9999999,123

Output:

42
1,234
6,368,745

See: https://regex101.com/r/oq67pb/2

0

The Answer here might be useful for your needs

(:?^|\s)(?=.)((?:0|(?:[1-9](?:\d*|\d{0,2}(?:,\d{3})*)))?(?:\.\d*[1-9])?)(?!\S)

This was the accepted answer to a similar question:

Regular expression to match numbers with or without commas and decimals in text

JRhino
  • 99
  • 2
  • 14