For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > October 2006 > replace letter o with 0









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author replace letter o with 0
John.Eberly@gmail.com

2006-10-19, 3:59 am

Hi,

I have data from an OCR feed that I need to clean up a little.

eg.
lO/18/2oo6~18:53~Fo6o1o2694~l~Ell M32~9o28 18th Av Sw~Medic Response

How can I replace all the "o" with "0" but only if the "o" is next to
another number.

If it is "Albion Ave" it should remain "Albion Ave", but
if it is "9o28" it should be changed to 9028 with perl.

Thanks

nikne

2006-10-19, 3:59 am

Hi
You can do this with the following method.

my $str = "lO/18/2oo6~18:53~Fo6o1o2694~l~Ell M32~9o28 18th Av Sw~Medic
Response";

if($str =~ /\do/g){
$str =~ s/o/0/ig;
print $str;
}

exit 0;

See I have checked it.
Its giving desired output.

Thanks
NN


John.Eberly@gmail.com wrote:
> Hi,
>
> I have data from an OCR feed that I need to clean up a little.
>
> eg.
> lO/18/2oo6~18:53~Fo6o1o2694~l~Ell M32~9o28 18th Av Sw~Medic Response
>
> How can I replace all the "o" with "0" but only if the "o" is next to
> another number.
>
> If it is "Albion Ave" it should remain "Albion Ave", but
> if it is "9o28" it should be changed to 9028 with perl.
>
> Thanks


Paul Lalli

2006-10-19, 7:56 am

nikne wrote:
> John.Eberly@gmail.com wrote:
[color=darkred]
> You can do this with the following method.
>
> my $str = "lO/18/2oo6~18:53~Fo6o1o2694~l~Ell M32~9o28 18th Av Sw~Medic
> Response";
>
> if($str =~ /\do/g){
> $str =~ s/o/0/ig;
> print $str;
> }
>
> exit 0;
>
> See I have checked it.
> Its giving desired output.


You have a funny definition of "desired" output. Your definition seems
to be "contrary to what was requested", rather than the traditional "in
agreement with what was requested."

For one, you're only checking one side of the o for a digit. The OP
specified "next to" without specifying which side, so we must assume
either. More importantly, if there is ANY instance of a digit to the
left of an o, you change ALL o's, including those not next to digits.

my $str = "lO/18/2oo6~18:53~Fo6o1o2694~l~Ell M32~9o28 18th Av Sw~Medic
Response";
$str =~ s/(?<=\d)o|o(?=\d)/0/g;
print "$str\n";

Paul Lalli

kens

2006-10-19, 7:56 am


nikne wrote:
> Hi
> You can do this with the following method.
>
> my $str = "lO/18/2oo6~18:53~Fo6o1o2694~l~Ell M32~9o28 18th Av Sw~Medic
> Response";
>
> if($str =~ /\do/g){
> $str =~ s/o/0/ig;
> print $str;
> }
>
> exit 0;
>
> See I have checked it.
> Its giving desired output.


No it is not.
You check in the 'if' statement to see that you have a number followed
by
'o', but in the substitution, you blindly substitute all 'o's with
'0's.

The following will probably work, but someone may have a more elegant
solution.

use strict;
use warnings;

while (<DATA> )
{
while(s/(\d)o/${1}0/g){};
print $_;
}
__DATA__
lO/18/2oo6~18:53~Fo6o1o2694~l~Ell M32~9o28 18th Av Sw~Medic Response

Output:
lO/18/2006~18:53~Fo60102694~l~Ell M32~9028 18th Av Sw~Medic Response

HTH,
Ken
[color=darkred]
>
> Thanks
> NN
>
>
> John.Eberly@gmail.com wrote:

kens

2006-10-19, 6:56 pm


kens wrote:
> nikne wrote:
>
> No it is not.
> You check in the 'if' statement to see that you have a number followed
> by
> 'o', but in the substitution, you blindly substitute all 'o's with
> '0's.
>
> The following will probably work, but someone may have a more elegant
> solution.
>
> use strict;
> use warnings;
>
> while (<DATA> )
> {
> while(s/(\d)o/${1}0/g){};


My code has the mistake Paul noted (only catches 'o' preceded by a
number).
You would have to add a second line to catch those with a following
number:

while(s/o(\d)/0${1}/g){};

I placed my statements in a while statement to catch the instances
where
you might have 'fooo2' as input and want 'f0002' as output, since after
each
iteration, you may have more 'o's next to numbers.
You could modify Paul's solution for the same effect:

while (s/(?<=\d)o|o(?=\d)/0/g){};

Ken
[color=darkred]
> print $_;
> }
> __DATA__
> lO/18/2oo6~18:53~Fo6o1o2694~l~Ell M32~9o28 18th Av Sw~Medic Response
>
> Output:
> lO/18/2006~18:53~Fo60102694~l~Ell M32~9028 18th Av Sw~Medic Response
>
> HTH,
> Ken
>

Barleyman

2006-10-19, 6:56 pm

Thanks kens/paul for your help, greatly appreciated.

I chose to go with the last solution posted for now. It is a little
more readable to me currently, but I plan to go over all of them to get
a better understanding.

Everything worked as planned in cleaning up my data. I still have some
issues with 1 vs. l, but I can apply the same logic you already gave me
to tackle that one.

Thanks again.


kens wrote:[color=darkred]
> kens wrote:
>
> My code has the mistake Paul noted (only catches 'o' preceded by a
> number).
> You would have to add a second line to catch those with a following
> number:
>
> while(s/o(\d)/0${1}/g){};
>
> I placed my statements in a while statement to catch the instances
> where
> you might have 'fooo2' as input and want 'f0002' as output, since after
> each
> iteration, you may have more 'o's next to numbers.
> You could modify Paul's solution for the same effect:
>
> while (s/(?<=\d)o|o(?=\d)/0/g){};
>
> Ken
>

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com