Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I am a newbie, so please be kind. I want to have a comma seperated number(every three digits). The following I have works for the first three digits, but if the number is 7 digits longs it doesnt add the comma. I know I'm missing something really simple.
$col=~s/(\d)(\d\d\d)$/$1,$2/g;

Replies are listed 'Best First'.
Re: simple regex
by Nkuvu (Priest) on Feb 26, 2004 at 19:22 UTC
    Found via perldoc -q comma:

    How can I output my numbers with commas added? This subroutine will add commas to your number: sub commify { local $_ = shift; 1 while s/^([-+]?\d+)(\d{3})/$1,$2/; return $_; } This regex from Benjamin Goldberg will add commas to numbers: s/(^[-+]?\d+?(?=(?>(?:\d{3})+)(?!\d))|\G\d{3}(?=\d))/$1,/g; It is easier to see with comments: s/( ^[-+]? # beginning of number. \d{1,3}? # first digits before first comma (?= # followed by, (but not included in the mat +ch) : (?>(?:\d{3})+) # some positive multiple of three digits. (?!\d) # an *exact* multiple, not x * 3 + 1 or whate +ver. ) | # or: \G\d{3} # after the last group, get three digits (?=\d) # but they have to have more digits after t +hem. )/$1,/xg;
Re: simple regex
by borisz (Canon) on Feb 26, 2004 at 19:14 UTC
    #!/usr/bin/perl $_ = '1234567'; $_ = reverse $_; s/(\d{3})(?=\d)/$1,/g; $_ = reverse $_; print $_ ;
    Boris
Re: simple regex
by NetWallah (Canon) on Feb 26, 2004 at 19:33 UTC

    Here is another way, based on the RE you used:

    The trick is to loop looking for groups of 3 digits.

    while($col=~s/(\d)(\d\d\d)(,|$)/$1,$2/) {}
    Notice - we look of either trailing COMMA or, end of line.

    "Experience is a wonderful thing. It enables you to recognize a mistake when you make it again."
Re: simple regex
by revdiablo (Prior) on Feb 26, 2004 at 19:38 UTC
    if the number is 7 digits longs it doesnt add the comma

    The reason is because you anchor your match to the end of the line with $. Your regex is doing exactly what you're asking it to do: match 4 digits at the end of the string, and insert a comma in the appropriate place.

    It's messy to write a "normal" regex to do what you want, because regular expressions scan your string from left to right. The easiest way commafy a number is to actually reverse the string first, as demonstrated by borisz's earlier post.

Re: simple regex
by Roger (Parson) on Feb 26, 2004 at 22:36 UTC
    Here's a more generic solution that I used to commafy not only integers, but also decimals.

    { local $_ = $amount; /\./ ? s/(?<=\d)(?=(\d{3})+(?:\.))/,/g : s/(?<=\d)(?=(\d{3})+(?!\d))/,/g; $amount = $_; }

    If you look under Q&A, you will find related topics on how to commafy a number. You should learn to use the Super Search feature of the Perl Monks site. A lot of the questions have been discussed in detail, you just have to search for them.