假设我想用以下内容替换文件中的字符串
name
nAmE
naMEbb
NAME
并且想将单词"name"替换为"dave",但保留原始文本的大写。例如,我想要的输出是,
dave
dAvE
daVEbb
DAVE
是否有任何一行程序可以做到这一点(最好是在Perl中,这样我就可以跨许多文件进行就地替换)?
编辑除非两个字符串的长度完全相同,否则问题是不明确的。
在perlFaq上有一些解决方案:http://perldoc.perl.org/perlfaq6.html How-do-I-substitute-case-insensitively-on-the-LHS-while-preserving-case-on-the-RHS ?
其中一个解决方案允许在单行中执行替换,通过定义子例程(preserve_case):
$string = "this is a TEsT case";
$string =~ s/(test)/preserve_case($1, "success")/egi;
print "$stringn";
打印:This is a SUcCESS case
这是疯狂的,但它的工作:
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";'
一行解决方案!
我想知道perlfaq中的示例是否适用于非ascii。不使用异或hack的变体可以是:
$text =~ s{$str_to_replace}{my $i=0;join "",map {substr($&,$i++,1)=~/p{IsLower}/?lc:uc} split //,$str_to_substitute}ieg;
但是这只在/i
修饰符是区域设置的情况下有效(参见perllocale)。