Skip
Skip

Reputation: 6531

Perl regex - why does the regex /[0-9\.]+(\,)/ match comma

The following seems to match , Can someone explain why?

I would like to match more than one Number or point, ended by comma.

 123.456.768,
 123,
 .,
 1.2,

But doing the following unexpectedly prints , too

my $text = "241.000,00";
foreach my $match ($text =~ /[0-9\.]+(\,)/g){
    print "$match \n";
}
print $text; 

# prints 241.000,
#        ,

Update:
The comma matched because: In list context, //g returns a list of matched groupings, or if there are no groupings, a list of matches to the whole regex As defined here.

Upvotes: 2

Views: 5087

Answers (5)

ikegami
ikegami

Reputation: 386406

You're capturing the wrong thing! Move the parens from around the comma to around the number.

$text =~ /([0-9\.]+),/g

Upvotes: 2

Patrick
Patrick

Reputation: 1837

You can replace the comma with a lookahead, or just exclude the comma altogether since it isn't part of what you want to capture, it won't make a difference in this case. However, the pattern as it is puts the comma instead of the number into capture group 1, and then doesn't even reference by capture group, returning the entire match instead.

This is how a capture group is retrieved:

$mystring = "The start text always precedes the end of the end text.";
if($mystring =~ m/start(.*)end/) {
    print $1;
}

Upvotes: 1

maerics
maerics

Reputation: 156572

Use a zero-width positive look-ahead assertion to exclude the comma from the match itself:

$text =~ /[0-9\.]+(?=,)/g

Upvotes: 4

Andrew Cheong
Andrew Cheong

Reputation: 30283

If you don't want to match the comma, use a lookahead assertion:

/[0-9\.]+(?=,)/g

Upvotes: 3

Schwern
Schwern

Reputation: 165298

Your match in the foreach loop is in list context. In list context, a match returns what its captured. Parens indicate a capture, not the whole regex. You have parens around a comma. You want it the other way around, put the parens aroundt he bit you want.

my $text = "241.000,00";

# my($foo) puts the right hand side in list context.
my($integer_part) = $text =~ /([0-9\.]+),/;

print "$integer_part\n";  # 241.000

Upvotes: 4

Related Questions