Как мне выполнить замену Perl в строке, сохранив оригинал?

StackOverflow https://stackoverflow.com/questions/22836

  •  09-06-2019
  •  | 
  •  

Вопрос

В Perl, каков хороший способ выполнить замену строки с помощью регулярного выражения и сохранить значение в другой переменной, не изменяя исходную?

Обычно я просто копирую строку в новую переменную, а затем привязываю ее к s/// регулярное выражение, которое выполняет замену в новой строке, но мне было интересно, есть ли лучший способ сделать это?

$newstring = $oldstring;
$newstring =~ s/foo/bar/g;
Это было полезно?

Решение

Это идиома, которую я всегда использовал, чтобы получить измененную копию строки без изменения оригинала:

(my $newstring = $oldstring) =~ s/foo/bar/g;

В perl 5.14.0 или более поздней версии вы можете использовать новый /r модификатор неразрушающей замены:

my $newstring = $oldstring =~ s/foo/bar/gr; 

Примечание:Вышеприведенные решения работают без g слишком.Они также работают с любыми другими модификаторами.

Другие советы

Заявление:

(my $newstring = $oldstring) =~ s/foo/bar/g;

Что эквивалентно:

my $newstring = $oldstring;
$newstring =~ s/foo/bar/g;

В качестве альтернативы, начиная с Perl 5.13.2, вы можете использовать /r чтобы выполнить неразрушающую замену:

use 5.013;
#...
my $newstring = $oldstring =~ s/foo/bar/gr;

Под use strict, сказать:

(my $new = $original) =~ s/foo/bar/;

вместо этого.

Однострочное решение более полезно в качестве шибболета, чем хороший код;хорошие программисты на Perl будут знать это и понимать, но это гораздо менее прозрачно и читабельно, чем двухстрочный куплет с копированием и изменением, с которого вы начинаете.

Другими словами, хороший способ сделать это - это то, как вы уже делаю это.Излишняя лаконичность в ущерб удобочитаемости - это еще не победа.

Другое решение, разработанное до версии 5.14: http://www.perlmonks.org/?node_id=346719 (см. сообщение Джефи)

В качестве своего подхода использует map, это также хорошо работает для массивов, но требует каскадирования map для создания временного массива (в противном случае оригинал был бы изменен):

my @orig = ('this', 'this sucks', 'what is this?');
my @list = map { s/this/that/; $_ } map { $_ } @orig;
# @orig unmodified

Я ненавижу фу и бар ..кто вообще придумал эти не описательные термины в программировании?

my $oldstring = "replace donotreplace replace donotreplace replace donotreplace";

my $newstring = $oldstring;
$newstring =~ s/replace/newword/g; # inplace replacement

print $newstring;
%: newword donotreplace newword donotreplace newword donotreplace

Если вы пишете Perl с use strict;, тогда вы обнаружите, что синтаксис в одну строку недопустим, даже если он объявлен.

С:

my ($newstring = $oldstring) =~ s/foo/bar/;

Вы получаете:

Can't declare scalar assignment in "my" at script.pl line 7, near ") =~"
Execution of script.pl aborted due to compilation errors.

Вместо этого синтаксис, который вы использовали, хотя и на строку длиннее, является синтаксически правильным способом сделать это с помощью use strict;.Для меня, используя use strict; теперь это просто привычка.Я делаю это автоматически.Каждый должен это делать.

#!/usr/bin/env perl -wT

use strict;

my $oldstring = "foo one foo two foo three";
my $newstring = $oldstring;
$newstring =~ s/foo/bar/g;

print "$oldstring","\n";
print "$newstring","\n";
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top