How to Replace Text while Maintaining Capitalization?
Say I wanted to a string replace on a file with the following contents
name
nAmE
naMEbb
NAME
And wanted to replace the word "name" with "dave", but keeping the capitalization of the original text. For example, my desired output would be,
dave
dAvE
daVEbb
DAVE
Are there any one-liners to do this (preferably in Perl so I can do an in-place substitution across many files)?
EDIT The problem is ambiguous unless both strings have exactly the same length. Let's assume it开发者_高级运维 does.
There are some solutions on perlFaq: http://perldoc.perl.org/perlfaq6.html#How-do-I-substitute-case-insensitively-on-the-LHS-while-preserving-case-on-the-RHS?
One of solutions presented there allows to perform the substitution in a single line, by defining a subroutine (preserve_case):
$string = "this is a TEsT case";
$string =~ s/(test)/preserve_case($1, "success")/egi;
print "$string\n";
This prints: this is a SUcCESS case
It's crazy but it works:
perl -e 'use List::MoreUtils "pairwise"; $_ = "toto naME nAmE"; s/(name)/@x = map(ord, split "", "DAVE"); @y = map(ord>=97?32:0, split "", $1); @c = map chr, pairwise { $a + $b } @x, @y; $" = ""; "@c";/gei; print "$_\n";'
one line solution!
I wonder whether the example from perlfaq works for non-ASCII. A variant that doesn't use the XOR hack could be:
$text =~ s{$str_to_replace}{my $i=0;join "",map {substr($&,$i++,1)=~/\p{IsLower}/?lc:uc} split //,$str_to_substitute}ieg;
But this only works if the /i
modifier is locale-enabled (see perllocale).
精彩评论