Regex 如何在保持大写的同时替换文本?

Regex 如何在保持大写的同时替换文本?,regex,string,perl,replace,Regex,String,Perl,Replace,假设我想用以下内容替换文件上的字符串 name nAmE naMEbb NAME 并想用“dave”替换“name”,但保留原文的大写字母。例如,我想要的输出是 dave dAvE daVEbb DAVE 是否有任何一行程序可以做到这一点(最好是Perl,这样我就可以跨多个文件进行就地替换) 编辑 除非两个字符串的长度完全相同,否则问题是不明确的。让我们假设是这样。perlFaq上有一些解决方案: ? 其中一种解决方案通过定义一个子例程(preserve_case),允许在一行中执行替换:

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

name
nAmE
naMEbb
NAME
并想用“dave”替换“name”,但保留原文的大写字母。例如,我想要的输出是

dave
dAvE
daVEbb
DAVE
是否有任何一行程序可以做到这一点(最好是Perl,这样我就可以跨多个文件进行就地替换)

编辑
除非两个字符串的长度完全相同,否则问题是不明确的。让我们假设是这样。

perlFaq上有一些解决方案: ?

其中一种解决方案通过定义一个子例程(preserve_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。 不使用XOR 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)时有效。

原始字符串和替代字符串的长度相同?否则,“同一案件”的定义就模棱两可
$text =~ s{$str_to_replace}{my $i=0;join "",map {substr($&,$i++,1)=~/\p{IsLower}/?lc:uc} split //,$str_to_substitute}ieg;