On 8/27/07, Mumia W. <[EMAIL PROTECTED]> wrote:
> On 08/27/2007 03:59 AM, Petra Vide Ogrin wrote:
> > Hi all,
> >
> > I have a hash and some prose text and want my perl to identify the keys of
> > the hash in this text and replace them with the corresponding values of
> > the keys.
> >
> > I tried the following
> >
> > foreach (keys %expan) {
> >   if ($sbl =~ m/$_/g) {
> >     $sbl =~ s/$_/$expan{$_}/g;
> >   }
> > }
> >
> > but it doesn't seem to work properly. What am I doing wrong?
> >
> > Thanks for the help,
> > best,
> > Petra
> >
>
> Try this (untested):
>
> my $keys = join('|',keys %expan);
> $sbl =~ s/($keys)/$expan{$1}/g;
>
> Read this: http://perldoc.perl.org/perlre.html
snip

Bad idea*, at least until Perl 5.10 (and maybe not even then).
Alternations are notoriously inefficient in Perl due to how the regex
engine works.  Perl 5.10 fixes this, at least somewhat, by using
something called Tries (which are something like trees, but I don't
fully understand them yet), but I haven't seen any numbers yet on how
much improvement we should expect (I will compile 5.9.5 today and
report back).

* They are so bad that even optimizing the regex down to /foo|ba[rz]/
doesn't help.

          Rate   join   hard joinqr    opt     qr
join   42708/s     --    -0%    -1%   -11%   -56%
hard   42708/s     0%     --    -1%   -11%   -56%
joinqr 43115/s     1%     1%     --   -11%   -56%
opt    48188/s    13%    13%    12%     --   -50%
qr     97303/s   128%   128%   126%   102%     --

my %subs = (
        'qr' => sub {
                my $t = $text;
                $t =~ s/$_->[0]/$_->[1]/g for @replace;
                return $t;
        },
        joinqr => sub {
                my $t = $text;
                $t =~ s/($re)/$replace{$1}/g;
                return $t;
        },
        join => sub {
                my $t = $text;
                $t =~ s/($str)/$replace{$1}/g;
                return $t;
        },
        hard => sub {
                my $t = $text;
                $t =~ s/(foo|bar|baz)/$replace{$1}/g;
                return $t;
        },
        opt =>  sub {
                my $t = $text;
                $t =~ s/(foo|ba[rz])/$replace{$1}/g;
                return $t;
        }
);

Benchmark::cmpthese(-1, \%subs);

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to