Perl在前一个模式匹配后无法工作

use*_*847 6 perl

我有一个奇怪的问题,即在s///前面的模式匹配之后,susbtitute运算符不起作用.例如

use strict; 
use warnings; 

my $var = "var"; 
$var =~ s||/|g; 

print "$var\n";
Run Code Online (Sandbox Code Playgroud)

输出是: /v/a/r/

但在这种情况下

use strict; 
use warnings; 

my $a = "test"; 

if ($a =~ /te/) { 

    my $var = "var"; 
    $var =~ s||/|g; 

    print "$var\n"; 
}
Run Code Online (Sandbox Code Playgroud)

输出是:var,它应该与前一个结果相同.

这里发生了什么?我该如何解决?

Bor*_*din 5

perlop有这个说空格局//

如果PATTERN求值为空字符串,则使用最后成功匹配的正则表达式.在这种情况下,只有空模式上的g和c标志才能被尊重; 其他标志取自原始模式.如果之前没有匹配,则会(静默地)将其视为真正的空模式(始终匹配).

因此,第一个情况下,不取代而空字符串,因为没有出现过以前的模式相匹配,而第二个来的成功匹配后tetest,所以它替换te无处不在var,因此没有任何影响.

该计划表明

use strict;
use warnings;

my $str = 'a/b/c';

if ($str =~ m{/}) {
  $str =~ s//x/g;
}

print $str;
Run Code Online (Sandbox Code Playgroud)

产量

axbxc
Run Code Online (Sandbox Code Playgroud)

唯一的例外是split命令中的模式,如果这是您指定的模式,它总是匹配空模式.

要解决这个问题,如果你真的想要匹配每个角色之前和之后的点,你可以使用/x修饰符为你的模式使用一个微不足道的空间,就像这样

use strict; 
use warnings; 

my $var_a = 'test'; 

if ($var_a =~ /te/) { 

    my $var_b = 'var'; 
    $var_b =~ s| |/|gx; 

    print "$var_b\n"; 
}
Run Code Online (Sandbox Code Playgroud)

产量

/v/a/r/
Run Code Online (Sandbox Code Playgroud)