use strict; use warnings; use re q{eval}; my @numbers = ( q{Number... ()}, q{Number... (1)}, q{Number... (12)}, q{Number... (123)}, q{Number... (1,234)}, q{Number... (12,345)}, q{Number... (123,456)}, q{Number... (1,234,567)}, q{Number... (12,345,678)}, q{Number... (123,456,789)}, q{Number... (1,234,567,890)}, q{Number... (1,234a)},); my $deCommafied; my $rxNumberGrps; $rxNumberGrps = qr {(?x) \D* (\d+) (?=,|\)) (?{$deCommafied .= $^N}) (?: (??{$rxNumberGrps}) | \)\z ) }; my $rxDeComma = qr {(?x) (?{$deCommafied = q{}}) $rxNumberGrps }; foreach my $number (@numbers) { print qq{$number - }, $number =~ m{$rxDeComma} ? qq{$deCommafied\n} : qq{no match\n}; }