Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re^2: multiple substitution

by naturalsciences (Beadle)
on Aug 25, 2012 at 10:08 UTC ( #989711=note: print w/ replies, xml ) Need Help??


in reply to Re: multiple substitution
in thread multiple substitution

Could you explain the code for a sec. Should those ! be /.

I can understand $string =~ s/(apples|oranges|bananas)/$replace{$1}/e would take the first match from string ($1). Then because the /e tag the second part in substitution would be value complement to the key ($1). What is the deal with the || (or?) statement. (I guess I'm mistaken with the ! elements) Would this (mine own )code work?
#!/usr/bin/perl -w use strict; use warnings; my @keys = qw(F29-2 F29-3 F29-4 F44-2 F53-2 F38-3 F12-2); my @vals = qw(F29B2 F29B3 F29B4 F44B2 F53B2 F38B3 F12B2); my %replace; @replace{@keys} = @vals; while (my $line = <>) { if($line =~ m/^\>/){my $name=$line;$name =~ s/(F29-2,F29-3,F29-4,F +44-2,F53-2,F38-3,F12-2)/$replace{$1}/;print $name;} elsif ($line!~m/^\>/){print $line;} }
Did not want to use some convoluted regexp patterns because they might be usable this time but not always. Want to learn the tehnique to do such list/hash substitutions as in original question.


Comment on Re^2: multiple substitution
Select or Download Code
Re^3: multiple substitution
by cheekuperl (Monk) on Aug 25, 2012 at 13:07 UTC
    Should those ! be / That ! is alright. Perl allows that.

    Could you explain the code for a sec.
    $replace{$1} || $1
    This part helps you replace the matched string with itself in case %replace does not have corresponding key. For example,

    Did not want to use some convoluted regexp
    Trust me, this is a simple regex. It can get a lot worse, if you delve deeper :)

    Want to learn the tehnique to do such list/hash substitutions as in original question
    As far as searching and replacing in strings is concerned, I guess regexes would be most helpful.
Re^3: multiple substitution
by Corion (Pope) on Aug 25, 2012 at 13:20 UTC
    If you are unfamiliar with s/// and s!!!, I already linked to the relevant documentation, perlop. Please read it. Regarding your own attempt, what happened when you tried it?
Re^3: multiple substitution
by AnomalousMonk (Monsignor) on Aug 25, 2012 at 17:28 UTC
    Did not want to use some convoluted regexp patterns ... Want to learn the tehnique to do such list/hash substitutions ...

    A common approach to handling long search/replace string lists is to generate the search regex automatically from the keys of the search/replace hash. (Then you just have to worry about getting the hash right!)

    >perl -wMstrict -le "my @keys = qw(F29-2 F29-3 F29-4 F44-2 F53-2 F38-3 F12-2); my @vals = qw(F29B2 F29B3 F29B4 F44B2 F53B2 F38B3 F12B2); my %replace; @replace{@keys} = @vals; ;; my $rx_search = join q{ | }, map quotemeta, keys %replace; $rx_search = qr{ $rx_search }xms; print $rx_search; ;; my $s = 'F99-9 FF29-22 -F29-2- F29-2 F44-2 F12-2'; print qq{'$s'}; my $t = $s; $t =~ s{ ($rx_search) }{$replace{$1}}xmsg; print qq{'$t'}; ;; $t = $s; $t =~ s{ \b ($rx_search) \b }{$replace{$1}}xmsg; print qq{'$t'}; ;; $t = $s; $t =~ s{ (?<! \S) ($rx_search) (?! \S) }{$replace{$1}}xmsg; print qq{'$t'}; " (?^msx: F29\-4 | F53\-2 | F44\-2 | F29\-2 | F38\-3 | F29\-3 | F12\-2 ) 'F99-9 FF29-22 -F29-2- F29-2 F44-2 F12-2' 'F99-9 FF29B22 -F29B2- F29B2 F44B2 F12B2' 'F99-9 FF29-22 -F29B2- F29B2 F44B2 F12B2' 'F99-9 FF29-22 -F29-2- F29B2 F44B2 F12B2'

    Note that none of the conversion examples use the  /e switch, which will make conversion slightly faster. In all the conversion examples, F99-9 is never converted: it just doesn't appear in the conversion  @keys array.

    In the first conversion example, the F29-2 substring in FF29-22 and -F29-2- is converted even though it is embedded in another string: it appears in the conversion list.

    This is fixed for FF29-22 in the second example by using  \b boundary assertions to allow conversion only if a search string is neither preceded nor followed by a 'word' character ([A-Za-z0-9_]), but this still allows the substring in -F29-2- to be replaced because '-' is not a word character.

    This problem (if problem it is) is fixed in the third example by using different boundary assertions:  (?<! \S) and  (?! \S) allow a match (and replacement) only if the potential match substring is neither preceded nor followed by a non-whitespace character.

    $name =~ s/(F29-2,F29-3,F29-4,F44-2,F53-2,F38-3,F12-2)/$replace{$1}/;

    Note that | (pipe) and not , (comma) is the alternation metacharacter.

    Update: aaron_baugher, in a reply already posted, gave an example of the automatic regex generation technique discussed above, but the examples of using boundary conditions to refine a match may still be useful.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://989711]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (14)
As of 2014-07-23 20:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (152 votes), past polls