Jim
Jim

Reputation: 19572

Can't I replace using the capturing groups?

In the following script I am trying to keep the decimal part and the first 2 fractional parts and the third if it is greater than 0.
So 12.37500000000392 should be replaced to 12.375

#!/usr/bin/perl  

use strict;  
use warnings;  

my $price = 12.37500000000392;  
print "price = $price \n";  
$price =~ s/([0-9]+)(\.[1-9]{2}[1-9]?)\d*?/$1$2/;   

print "1 = $1 \n";  
print "2 = $2 \n";  
print "price = $price \n"; 

But it does not work.
It shows that $1 is 12 and $2 is .375 but the price in the end is still printed as 12.37500000000392 in the last print statement

Upvotes: 1

Views: 122

Answers (2)

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89557

You can do it with:

$price =~ s/\.\d{2}[1-9]?\K\d*//;

Upvotes: 1

Martin Ender
Martin Ender

Reputation: 44259

The problem is the ungreedy repetition at the end. Just use

$price =~ s/([0-9]+)(\.[1-9]{2}[1-9]?)\d*/$1$2/;

Since the ? makes the * match as few repetitions as possible - and there are no further conditions at the end of the pattern that could make it fail - 0 repetitions of \d is the fewest possible, so the remaining digits are simply never matched, and hence not replaced.

Note that your pattern doesn't match at all if one of the first two digits is a zero. You probably wanted to use

$price =~ s/([0-9]+)(\.[0-9]{2}[1-9]?)\d*/$1$2/;

Also, if you don't need the integer and fractional parts later on, you could slightly simplify the entire thing like this:

$price =~ s/([0-9]+\.[0-9]{2}[1-9]?)\d*/$1/;

Upvotes: 4

Related Questions