如何在表达式中使用Perl的///?

时间:2010-04-19 01:47:58

标签: python regex perl variable-assignment substitution

我头疼的寻找这个: 如何在表达式中使用s ///而不是赋值。为了澄清我的意思,我在下面的上下文中使用时,我正在寻找一个perl等效的python的 re.sub(...)

newstring = re.sub('ab', 'cd', oldstring)

到目前为止,我知道如何在perl中执行此操作的唯一方法是:

$oldstring =~ s/ab/cd/;
$newstring = $oldstring;

请注意额外的作业。

5 个答案:

答案 0 :(得分:11)

您可以使用($new = $old) =~ s/whatever/whateverelse/;获得与您正在寻找的完全相同的功能:

use strict;
my $old = "OLD";
my $new;
($new = $old) =~ s/OLD/NEW/;
print "old=$old, new=$new";

产地:

old=OLD, new=NEW

正是你想要的

如果您正在寻找一个功能,您可以定义自己的功能以避免分配:

use strict;
sub re_sub { 
   my ($find, $replace, $old) = @_;
   my $new = $old;
   $new =~ s/$find/$replace/;
   return $new;
}

my $old = "ab";
my $new = re_sub('ab', 'cd', $old);
print "new=$new\n";

new=cd中的结果。

答案 1 :(得分:7)

Perl的正则表达式替换总是“就地”发生。因此,您需要将字符串复制到新变量并对新变量进行操作:

(my $newstring = $oldstring) =~ s/ab/cd/;

答案 2 :(得分:7)

您似乎对=~的工作方式存在误解。 =~是一个绑定运算符,它将变量与regexp运算符相关联。它没有做任何任务。

regexp运算符默认使用主题变量$_,因此s/foo/bar/;$_ =~ s/foo/bar/;相同。没有分配。主题变量已转换。

在操作任何其他变量时,情况类似。 $var =~ s/foo/bar/;通过将$var的第一个实例替换为foo来转换bar。没有分配。

我能给你的最好建议是用Python编写Python,用Perl编写Perl。不要指望两种语言是一样的。

您可以像DVK建议的那样做并编写一个子程序来重现您习惯的替换行为。

或者你可以尝试一些惯用的Perl。基于您表达的在一行中应用多个转换的愿望,我提供了一些您可能会觉得有用的示例。

在这里,我在一个项目上使用for循环来主题化$var并应用许多硬编码转换:

for( $var ) {
    s/foo/bar/;
    s/fizz/buzz/;
    s/whop/bop-a-loo-bop/;
    s/parkay/butter/;
    s/cow/burger/;
}

或者您可能需要应用一组可变变换。我定义了一个子例程来循环定义旧/新转换对的数组引用列表。此示例利用Perl的面向列表的参数处理来处理任意数量的转换。

my $foo = transform(
    'abcd' =>
    [ 'a',  'b'    ], 
    [ 'bb', 'c'    ],
    [ 'cc', 'd'    ],
    [ 'dd', 'DONE' ],
);

sub transform {
    my $var = shift;
    for (@_ ) {
        my ($old, $new) = @$_;
        $var =~ s/$old/$new/;
    }

    return $var;
}

最后有点乱七八糟地提供修改其第一个参数的转换版本:

my $foo = 'abcd';

transform_in_place(
    $foo =>
    [ 'a',  'b'    ], 
    [ 'bb', 'c'    ],
    [ 'cc', 'd'    ],
    [ 'dd', 'DONE' ],
);

print "$foo\n";

sub transform_in_place {
    for my $i (1..$#_ ) {
        my ($old, $new) = @{$_[$i]};
        $_[0] =~ s/$old/$new/;
    }
}

对于我自己的项目,我可能会根据特定问题的需要使用前两个选项中的一个。

答案 3 :(得分:2)

你想让$ newstring成为替换的结果,对吧?

这样的事情:

($newstring = $oldstring) =~ s/ab/cd;

应该有效。作业将$newstring设置为$oldstring,然后评估为$newstring,这就是替换所依据的行为。

答案 4 :(得分:1)

基于此,我是否正确地假设你不能在一行中有两个// //,一个使用另一行的结果,没有中间分配? - 迈克

是的,你是对的。 如果你想对我要做的同一个字符串应用多个替换

    $newstring = $oldstring ;
    $newstring  =~ s/ab/cd/ ;
    $newstring  =~ s/xx/yy/ ;

以下操作无效,因为s//会返回所做的替换次数,而不是更改后的字符串。

    $newstring = $oldstring) =~ s/ab/cd/ =~ s/xx/yy/ ;

总之,Perl的正则表达式操作与Python非常不同,你最好从头开始学习Perl的功能,而不是试图将Python概念映射到Perl上