如何在保持资本化的同时替换文本?

时间:2011-08-09 20:55:44

标签: regex string perl replace

假设我想在具有以下内容的文件上替换字符串

name
nAmE
naMEbb
NAME

并希望将“name”替换为“dave”,但保留原始文本的大小写。例如,我想要的输出是,

dave
dAvE
daVEbb
DAVE

是否有任何单行代码(最好是在Perl中,所以我可以在许多文件中进行就地替换)?

修改 除非两个字符串具有完全相同的长度,否则问题是不明确的。我们假设它确实如此。

3 个答案:

答案 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)。