Regex 为什么这个perl正则表达式不起作用?

Regex 为什么这个perl正则表达式不起作用?,regex,perl,Regex,Perl,我有这个数组 my @input = ("He walk+V3SG very fast.", "He study+V3SG hard."); 我想把“步行+V3SG”和“学习+V3SG”替换为“步行”和“学习” 下面是我写的剧本。我认为这应该行得通,但由于某种原因,它不起作用 foreach my $sent(@input){ if ($sent =~ m/\Q+V3SG/){ if ($sent =~ m/\Q[dlr]y+V3SG/){

我有这个数组

my @input = ("He walk+V3SG very fast.", "He study+V3SG hard.");
我想把“步行+V3SG”和“学习+V3SG”替换为“步行”和“学习”

下面是我写的剧本。我认为这应该行得通,但由于某种原因,它不起作用

    foreach my $sent(@input){
    if ($sent =~ m/\Q+V3SG/){
        if ($sent =~ m/\Q[dlr]y+V3SG/){
            $sent =~ s/\Q[dlr]y+V3SG/ies/g;
        }
        if ($sent =~ m/\Q[s|x|sh|ch|o]+V3SG/){
            $sent =~ s/\Q[s|x|sh|ch|o]+V3SG/es/g;
        }
        else {$sent =~ s/\Q+V3SG/s/g}
    }
}

foreach my $sent(@input){
    print $sent;
    print "\n";
}

有人能告诉我脚本有什么问题吗?

这个
\Q
使剩余的正则表达式按字面意思匹配
[dlr]y+V3SG
。移动它可以使角色类正常工作:

s/[dlr]\Qy+V3SG/ies/g
或者只需退出
+

s/[dlr]y\+V3SG/ies/g
更改后,您将获得,例如:

He stuies hard.
要确保保留第一个字母,可以使用捕获或
\K
(从5.10开始):

对于第二个正则表达式,您使用了错误的括号:

s/(s|x|sh|ch|o)\Q+V3SG/$1es/g

您应该将
\Q
放在文本前面。您将它放在整个正则表达式之前,因此整个正则表达式被视为文字,而不被解释

第二件事你应该明智地使用
\K
来代替。把它放在你不想替换的零件后面。例如:
s/[dlr]\Ky\Q+V3SG/ies/g
进行
研究
研究
,它不会从结果中删除
d
l
r

第三件事
[s|x | sh | ch | o]
不会做你想的事。它将匹配
s、x、h、|、c、o
中的任何字符。正确的应该是
(?:s | x | sh | ch | o)
(?:…)
用于非捕获组

最后,这根本不应该是if/elsif/else。这个句子可以包含所有三种形式

总体而言:它为我们提供了:

#!/usr/bin/perl
use strict;
use warnings;

my @input = ("He walk+V3SG very fast.", "He study+V3SG hard.","He crush+V3SG hard.");

foreach (@input){
    if (m/\Q+V3SG/){
        s/[dlr]\Ky\Q+V3SG/ies/g;
        s/(?:s|x|sh|ch|o)\K\Q+V3SG/es/g;
        s/\Q+V3SG/s/g;
    }
}

foreach my $sent(@input){
    print $sent;
    print "\n";
}

此外,他们根本不应该使用if/elsif/else。这个句子可以包含所有三种形式。
#!/usr/bin/perl
use strict;
use warnings;

my @input = ("He walk+V3SG very fast.", "He study+V3SG hard.","He crush+V3SG hard.");

foreach (@input){
    if (m/\Q+V3SG/){
        s/[dlr]\Ky\Q+V3SG/ies/g;
        s/(?:s|x|sh|ch|o)\K\Q+V3SG/es/g;
        s/\Q+V3SG/s/g;
    }
}

foreach my $sent(@input){
    print $sent;
    print "\n";
}