【问题标题】:How to Replace Text while Maintaining Capitalization?如何在保持大写的同时替换文本?
【发布时间】:2011-10-23 14:10:04
【问题描述】:

假设我想用以下内容对文件进行字符串替换

name
nAmE
naMEbb
NAME

并且想用“dave”替换“name”这个词,但保留原文的大写。例如,我想要的输出是,

dave
dAvE
daVEbb
DAVE

是否有任何单行程序可以做到这一点(最好是在 Perl 中,这样我就可以在许多文件中进行就地替换)?

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

【问题讨论】:

  • 原字符串和替换字符串长度一样吗?否则“相同情况”的定义是模棱两可的

标签: regex string perl replace


【解决方案1】:

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";

打印:这是一个成功案例

【讨论】:

    【解决方案2】:

    这很疯狂,但它确实有效:

    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";'
    

    单线解决方案!

    【讨论】:

      【解决方案3】:

      我想知道 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)。

      【讨论】:

        猜你喜欢
        • 2022-01-03
        • 2011-06-26
        • 1970-01-01
        • 2012-09-29
        • 2022-01-16
        • 1970-01-01
        • 1970-01-01
        • 2013-04-29
        • 1970-01-01
        相关资源
        最近更新 更多