in reply to Respect case in substitution

s/\b(find)\b/ uc('repl') | ( $1 ^ uc($1) ) /eig;

Only guaranteed to work for search strings and replacement strings consisting entirely of ASCII letters. Non-letter and accented characters won't work. EBCDIC won't work. It also only works if $1 and $find are the same length.

Update: Added clarification (by adding "guaranteed") and an extra failure mode.

Replies are listed 'Best First'.
Re^2: Respect case in substitution
by graff (Chancellor) on Feb 27, 2008 at 18:33 UTC
    What is your definition of "won't work" here?
    #!/usr/bin/perl -l use strict; my $find="find=1"; my $repl="repl:2"; for my $trial (qw/find=1 Find=1 FIND=1 fInD=1/) { $_ = "here is >$trial< data"; s/\b($find)\b/ uc($repl) | ( $1 ^ uc($1) ) /eig; print }
    For me, that produces:
    here is >repl:2< data here is >Repl:2< data here is >REPL:2< data here is >rEpL:2< data
    Do you see something wrong with that? I'll grant that many accented characters won't work properly, in the sense that you'll get an incorrect character as the result, but actually, there are a fair number of them where the case distinction is a matter of a single bit being on or off (just like in the ASCII letters), and I'd expect those to work. (But I don't have time to test that just now -- and I'm sure not going to argue about EBCDIC...)

      It will *happen* to work for some invalid inputs. Here are cases that support what I said:

      Non-letters in $repl:

      my $find= "find"; my $repl= "@@@@"; $_ = "Find"; print; s/\b($find)\b/ uc($repl) | ( $1 ^ uc($1) ) /eig; print; # @``` # Should be @@@@

      Non-letters in $find:

      my $find= chr(1234) . 'find'; my $repl= "aaaaa"; $_ = chr(1234) . 'FiNd'; print; s/\b($find)\b/ uc($repl) | ( $1 ^ uc($1) ) /eig; print; # AAaAa # Should be aAaAa