Reputation: 19572
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
Reputation: 89557
You can do it with:
$price =~ s/\.\d{2}[1-9]?\K\d*//;
Upvotes: 1
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