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;