假设我想在具有以下内容的文件上替换字符串
name
nAmE
naMEbb
NAME
并希望将“name”替换为“dave”,但保留原始文本的大小写。例如,我想要的输出是,
dave
dAvE
daVEbb
DAVE
是否有任何单行代码(最好是在Perl中,所以我可以在许多文件中进行就地替换)?
修改 除非两个字符串具有完全相同的长度,否则问题是不明确的。我们假设它确实如此。
答案 0 :(得分:8)
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 "$string\n";
这打印:这是一个SUcCESS案件
答案 1 :(得分:0)
这很疯狂,但确实有效:
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";'
一线解决方案!
答案 2 :(得分:0)
我想知道perlfaq的例子是否适用于非ASCII。 不使用XOR黑客的变体可能是:
$text =~ s{$str_to_replace}{my $i=0;join "",map {substr($&,$i++,1)=~/\p{IsLower}/?lc:uc} split //,$str_to_substitute}ieg;
但这仅在/i
修饰符启用了区域设置时才有效(请参阅perllocale)。