Как заменить текст при сохранении заглавных букв? - PullRequest
8 голосов
/ 10 августа 2011

Скажем, я хотел заменить строку в файле следующим содержимым

name
nAmE
naMEbb
NAME

И хотел заменить слово «имя» на «Дейв», но сохранив заглавные буквы исходного текста.Например, мой желаемый вывод будет:

dave
dAvE
daVEbb
DAVE

Есть ли однострочные для этого (желательно в Perl, чтобы я мог выполнять замену на месте для многих файлов)?* РЕДАКТИРОВАТЬ Проблема неоднозначна, если обе строки не имеют одинаковую длину.Давайте предположим, что это так.

Ответы [ 3 ]

8 голосов
/ 10 августа 2011

Существует несколько решений для 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";

Это печатает: это дело УСПЕХА

0 голосов
/ 10 августа 2011

Интересно, работает ли пример из 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).

0 голосов
/ 10 августа 2011

Это безумие, но оно работает:

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

решение в одну строку!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...