http://www.perlmonks.org?node_id=1056105


in reply to Re^2: iterating hash keys?
in thread iterating hash keys?

"Well, comparing to what I had, your code is faster than the speed of light!"

That's a good start. :-)

"Is there a simple way for the s// to also include names with hyphens in the middle?"

The short answer is: yes. The longer answer depends on details. I found a reference you made to input data with hyphens in "Re^8: using hashes"; however, you provided no indication of the output you wanted (except that 20-10,25 was the wrong output when bana-na,banana was the input).

The following is based on the code I provided earlier. Given these input files:

$ cat pm_1055846_name_id_data.txt bananas 456 oranges 23 peaches 897236 kiwis 3726 banana 25 bana 20 bana-na 15 na 10
$ cat pm_1055846_name_replace_data.txt bananas,oranges peaches,peaches,peaches kiwis oranges kiwis,oranges,bananas,bananas bananas,oranges,pineapples,peaches,kiwis bana-na,banana ba-na-na,bana-bana,bana-nana

If you want output like this:

$ cat pm_1055846_name_replaced_out.txt 456,23 897236,897236,897236 3726 23 3726,23,456,456 456,23,pineapples,897236,3726 15,25 ba-10-10,20-20,20-nana

Change

my $re = '\b(' . join('|', keys %id_for) . ')\b';

to

my $re = '\b(' . join('|', sort { $b cmp $a } keys %id_for) . ')\b';

If you want output like this:

$ cat pm_1055846_name_replaced_out.txt 456,23 897236,897236,897236 3726 23 3726,23,456,456 456,23,pineapples,897236,3726 15,25 ba-na-na,bana-bana,bana-nana

Change

my $re = '\b(' . join('|', keys %id_for) . ')\b';

to

my $re = '(^|,)(' . join('|', sort { $b cmp $a } keys %id_for) . ')(?= +,|$)';

and

s/$re/$id_for{$1}/g;

to

s/$re/$1$id_for{$2}/g;

If you want something different to these, and are unable to work it out for yourself, provide details as outlined in the "How do I post a question effectively?" guidelines.

It would also be useful to advise what version of Perl you're using: I wrote those changes for v5.8; a more efficient version could have been written for a later version. As a hint for doing this yourself, see (?<=pattern) \K under Look-Around Assertions in "perlre: Extended Patterns" — \K was introduced in v5.10.0 (see "perl5100delta: Regular expressions" for this, and other, regex enhancements).

-- Ken

Replies are listed 'Best First'.
Re^4: iterating hash keys?
by R56 (Sexton) on Sep 30, 2013 at 14:12 UTC

    It's the second case: total recognition of the exact pattern, or just let it go.

    I'm using 5.16, but will take a look into those changes though.

    Once again, many thanks for your help Ken :)