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

时间:2016-04-26 10:08:13

标签: 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/){
            $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";
}

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

2 个答案:

答案 0 :(得分:2)

\Q使正则表达式的其余部分按字面[dlr]y+V3SG进行。移动它可以使字符类正常运行:

s/[dlr]\Qy+V3SG/ies/g

或者只是逃避+

s/[dlr]y\+V3SG/ies/g

在这次改变之后,你会得到,例如:

He stuies hard.

为确保保留第一个字母,您可以使用捕获或\K(自5.10起):

s/[dlr]\K\Qy+V3SG/ies/g

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

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

答案 1 :(得分:0)

你应该在文字之前保留\Q。你把它放在整个正则表达式之前,所以整个正则表达式被认为是文字的,不会被解释。

第二件事你应该明智地用\K代替。把它放在你不想替代的部分之后。例如:s/[dlr]\Ky\Q+V3SG/ies/g生成study studies,并且不会从结果中删除dlr

第三件事[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";
}