我有这个数组。
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";
}
谁能告诉我脚本有什么问题?
答案 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
,并且不会从结果中删除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";
}