replace string with variable

A

aca

Thanks Gunnar and all others for your answers, I'm overwhelmed
for the answers. Please dont waste more time in this item.

I'm use the s/// the following manner:

#!/perl/bin
# Uso: perl font.pl <ficheroentrada >ficherosalida

while(<STDIN>)
{

s/(\.\d*[1-9])0+\b|\.0*(?!\d)/$l or ''/eg;
print; # print modified $_
}

Thanks to all and sorry if any of my messages are incorrect for the
this group.

ACA.
 
I

Ingo Menger

Bernard said:
Ingo Menger said:
Anno said:
Hi, from Spain, I'm new user in perl, I have a problem with
regular expression,

I dont know how I can replace the zeros on the right of the
decimal separator, for example I have a file with some lines of
data how this example:

20.1300,20.2500,19.7700,20.2500,985365,0

And I want that the final text appear how this

20.13,20.25,19.77,20.25,985365,0

I try use the regular expression but the final patron I dont
know how it can
be variable.

That's a number-formatting problem. A regular expression is not
the tool most suited for that. Use sprintf():

No! sprintf "%g" is not at all a tool for formatting decimal
numbers! [...]


Umm, OK, fine, but why are you yelling?

I did not intend to yell. I just wanted to warn of serious bugs. The
suggestion to do manipulation of strings that appear to be decimal
numbers by use of sprintf %g is just plain wrong. This is a FAQ, see
perldoc -q decimal
 
A

axel

Lars Haugseth said:
* (e-mail address removed) wrote:
|
|
| > I dont know how I can replace the zeros on the right of the decimal
| > separator, for example I have a file with some lines of data how this
| > example:
| >
| > 20.1300,20.2500,19.7700,20.2500,985365,0
| >
| > And I want that the final text appear how this
| >
| > 20.13,20.25,19.77,20.25,985365,0
|
| $str =~ s/0+,/,/g;
This will not work if the data contains integers with 0 as the last digit.
It will also fail to process the last number on each line.

I suddenly realised that after I had posted and cancelled the post...
too much wine last night ans not enough coffee this morning... :(

Axel
 
D

Dr.Ruud

Mirco Wahab schreef:
Dr.Ruud:
$ echo "10.00,20.1300,20.2500,19.7700,20.2500,985365,0.010" | perl
-pe ' s/\b(\d+[.]\d*?)0+\b/$1/g, s/[.](\D)/$1/g
'

$text = "200.,200.000,200,200.0";
$text =~ s/\b(\d+[.]\d*?)0+\b/$1/g, s/[.](\D)/$1/g;

You changed the code too much, the substitution after the comma operator
doesn't operate on your $text.

s/a/b/g, s/bb/c/g for $text ;


print "$text";

See: perldoc -q "quoting"



Improvement is still possible:

perl -le '
$_ = "10.00,20.1300,20.2500,19.7700,20.2500,985365,0.0";
s/([.]\d*?)0+(?=,|$)/$1/g, s/[.](?=,|$)//g ;
print
'

perl -le '
$_ = "10.00,20.1300,20.2500,19.7700,20.2500,985365,0.0";
s/(?:[.]0*|([.]\d*?)0+)(?=,|$)/$1/g ;
print
'
 
T

Tad McClellan

Mirco Wahab said:
Thus spoke Tad McClellan (on 2006-05-29 15:15):


Note that the OP does NOT want to "replace" them, but rather "delete" them.

Which I paraphrase as:

Delete insignificant trailing zeros

for example I have a file with some lines of data how this
example:

20.1300,20.2500,19.7700,20.2500,985365,0

And I want that the final text appear how this

20.13,20.25,19.77,20.25,985365,0


s/([\d.]+)/ $1+0 /ge;

Really cool one,


I call it "MacGyver style" programming.

perl's number-to-string DWIMery deletes insignificant trailing zeros,
so all I had to do was get perl to use that n2s dwimery for my
own purposes.

Of course, perl's dwimery also deletes insignificant _leading_
zeros (00200 => 200), and might even _add_ characters while
deleting others (.00100 => 0.001).

But, since the specification did not say what to do with leading
insignificant zeros, the developer is free to choose for themselves
what should be done with them.

So, in the interest of expediency, I chose to delete them too. :)

but:

my $text = qq{99.00000022222223};
$text=~ s/([\d.]+)/$1+0/ge;
print $text;

==> 99.0000002222222


The OP said he wants 20.1300 => 20.13, which in my mind is saying
that he wants to throw away some precision.

So worrying about the meaning and intricacies of "precision" can
be dispensed with for the OP's application. :) :)
 
X

Xicheng Jia

Mirco said:
Thus spoke Dr.Ruud (on 2006-05-29 16:50):
Mirco Wahab schreef:
Dr.Ruud:
$ echo "10.00,20.1300,20.2500,19.7700,20.2500,985365,0.010" | perl
-pe ' s/\b(\d+[.]\d*?)0+\b/$1/g, s/[.](\D)/$1/g
'
$text = "200.,200.000,200,200.0";
$text =~ s/\b(\d+[.]\d*?)0+\b/$1/g, s/[.](\D)/$1/g;

You changed the code too much, the substitution after the comma operator
doesn't operate on your $text.

s/a/b/g, s/bb/c/g for $text ;

Yes, you are right. My only excuse would be incompetence
(for not seeing the loop context from perl -pe) ...
Improvement is still possible:
perl -le '
$_ = "10.00,20.1300,20.2500,19.7700,20.2500,985365,0.0";
s/([.]\d*?)0+(?=,|$)/$1/g, s/[.](?=,|$)//g ;
print
'
perl -le '
$_ = "10.00,20.1300,20.2500,19.7700,20.2500,985365,0.0";
s/(?:[.]0*|([.]\d*?)0+)(?=,|$)/$1/g ;
print
'

OK, now it (2&3) seem to work, if we compare:
$text = "200.,200.000,200,200.0";

Note: from "Mastering Regular Expression" 2nd edition, by J. Friedl.

6.4.6.4 Needless character class elimination

A character class with a single character in it is a bit silly because
it invokes the processing overhead of a character class, but without
any benefits of one. So, a smarter implementation internally converts
something like [.] to \.
1)
s/\b(\d+[.]\d*?)0+\b/$1/g, s/[.](\D)/$1/g for $text;
==> 200,200,200,200.

2)
s/([.]\d*?)0+(?=,|$)/$1/g, s/[.](?=,|$)//g for $text;
==> 200,200,200,200

3)
s/(?:[.]0*|([.]\d*?)0+)(?=,|$)/$1/g for $text;

This is fine if you use it at one-liner and dont issue "-w" option. you
can use Gunnar's method to elimilate the warning info anyway.

$test =~ s/(?:\.0*|(\.\d*?)0+)(?=,|$)/$1 or ""/eg;

BTW. why you'd use the "for" loop on a scalar variable??:)

Xicheng
 
D

Dr.Ruud

Xicheng Jia schreef:
Note: from "Mastering Regular Expression" 2nd edition, by J. Friedl.

6.4.6.4 Needless character class elimination

A character class with a single character in it is a bit silly because
it invokes the processing overhead of a character class, but without
any benefits of one. So, a smarter implementation internally converts
something like [.] to \.

I prefer "[.]" to "\." and only use "\." when speed is important.
Some next version of perl will internally optimise ANYOF[x] to EXACT
BTW. why you'd use the "for" loop on a scalar variable??:)

Why not?

s/a/b/g, s/bb/c/g for $text ;


versus

do {local $_ = $text; s/a/b/g; s/bb/c/g }
 
I

Ingo Menger

Bernard said:
I don't need you to quote me the FAQ. It wasn't *what* you said, but *how* you said it that
spurred me to respond.

I apologize for that. However, it's not always easy to express the
right emotions when one writes in a foreign language.
 
M

Mirco Wahab

Thus spoke Bernard El-Hagin (on 2006-05-30 08:44):
I don't need you to quote me the FAQ. It wasn't *what* you said, but *how* you said it that
spurred me to respond. Just relax, it's not like anyone's life is at stake here.

This remembers me for some Startrek movie,
when a young technician yells at ole' Scotty:
"didn't you read the manuals" (when Scotty
decided: "give the engine 130%" or something).

Of course, Scotty "wrote the manuals" himself,
so it turned out to be a good joke for all
involved.

Regards

Mirco
 
C

cmic

Mirco Wahab a écrit :
Thus spoke cmic (on 2006-05-29 13:07):


No, wont work:

$text = "200.,200.0000";
my @fields = split /(?<!0)0*?,/, $text;
my $text = join ',', @fields;
print $text;

==> 200.,200.0000

OK. You're right. But your solution doesn't work either. The problem is
because the last number is *not* followed by a comma.

$text = "200.,200.0000";
my @fields = split /(?<=[^0])0*,/, $text;
my $new_text = join ',', @fields;

==> 200.,200.0000

As a perl beginner, I cannot solve (yet) with a split :-(
Regards.
 
X

Xicheng Jia

cmic said:
Mirco Wahab a écrit :
Thus spoke cmic (on 2006-05-29 13:07):


No, wont work:

$text = "200.,200.0000";
my @fields = split /(?<!0)0*?,/, $text;
my $text = join ',', @fields;
print $text;

==> 200.,200.0000

OK. You're right. But your solution doesn't work either. The problem is
because the last number is *not* followed by a comma.

$text = "200.,200.0000";
my @fields = split /(?<=[^0])0*,/, $text;
my $new_text = join ',', @fields;

==> 200.,200.0000

As a perl beginner, I cannot solve (yet) with a split :-(

try this one:

my @fields = split /\.?0*(?:,|$)/, $text;

Xicheng
 
C

Charles DeRykus

aca said:
Thanks Gunnar and all others for your answers, I'm overwhelmed
for the answers. Please dont waste more time in this item.

I'm use the s/// the following manner:

#!/perl/bin
# Uso: perl font.pl <ficheroentrada >ficherosalida

while(<STDIN>)
{

s/(\.\d*[1-9])0+\b|\.0*(?!\d)/$l or ''/eg;
print; # print modified $_
}

Thanks to all and sorry if any of my messages are incorrect for the
this group.

But, wait...there're more :)

Here's a commented solution which might be clearer. (wasn't sure
about items like .05000 but this will handle those too):


$text =~ s{ (\d+) ? # opt. 1 more digits
(\.) ? # opt. literal dot
(\d*[1-9])? # opt. 0/many digits w/trailing non-0 digit
(0+) ? # opt. 1/many trailing 0's
(,|\Z) # comma or string end
}
{ do { local $_;
$_ = "$1$5" if defined $1 and ( !defined $2
or (defined $2 and !defined $3) );
$_ = "$1.$3$5" if defined $1 and defined $2
and defined $3;
$_ = "$2$3$5" if !defined $1 and defined $2
and defined $3;
$_ };
}gex;
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top