Perl的QR //和替换
-
11-07-2019 - |
题
我在写一个小程序使用Getops这需要用户输入,并在此基础上,该计划将可尝试以匹配匹配什么对一些文本的模式,或替代文本。
时遇到的问题是,我不能得到的替代部分的工作。我在看的QR //手册页中的条目: HTTP ://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators 的,但我并没有任何与它的运气。我想我的代码模型完全一样在这种情况下的文档。我编译一个匹配模式,以及替代品为替代。
有人能指出我要去哪里错了吗? (别担心安全太多了,这仅仅是个人使用的小脚本)
下面就是我在寻找:
if($options{r}){
my $pattern = $options{r};
print "\nEnter Replacement text: ";
my $rep_text = <STDIN>;
#variable grab, add flags to pattern if they exist.
$pattern .= 'g' if $options{g};
$pattern .= 'i' if $options{i};
$pattern .= 's' if $options{s};
#compile that stuff
my $compd_pattern = qr"$pattern" or die $@;
print $compd_pattern; #debugging
print "Please enter the text you wish to run the pattern on: ";
my $text = <STDIN>;
chomp $text;
#do work and display
if($text =~ s/$compd_pattern/$rep_text/){ #if the text matched or whatever
print $text;
}
else{
print "$compd_pattern on \n\t{$text} Failed. ";
}
} #end R FLAG
当我与-r运行它“/无光泽/” -i,并输入替换文本“马修”,对文本“无光泽”,它失败。这是为什么?
编辑:
感谢您的答案家伙!这是真的非常有帮助。我结合您的两个建议纳入工作解决问题的办法。我不得不有点不同处理/ g标志。下面是工作样品:
if($options{r}){
my $pattern = $options{r};
print "\nEnter Replacement text: ";
my $rep_text = <STDIN>;
chomp $rep_text;
#variable grab, add flags to pattern if they exist.
my $pattern_flags .= 'i' if $options{i};
$pattern_flags .= 's' if $options{s};
print "Please enter the text you wish to run the pattern on: ";
my $text = <STDIN>;
chomp $text;
#do work and display
if($options{g}){
if($text =~ s/(?$pattern_flags:$pattern)/$rep_text/g){ #if the text matched or whatever (with the g flag)
print $text;
}
else{
print "$pattern on \n\t{$text} Failed. ";
}
}
else{
if($text =~ s/(?$pattern_flags:$pattern)/$rep_text/){ #if the text matched or whatever
print $text;
}
else{
print "$pattern on \n\t{$text} Failed. ";
}
}
} #end R FLAG
解决方案
混沌指出,你会使用qr//
遇到一些困难。你真的需要预编译的模式?如果没有,像这样的策略可能会奏效:
my $pattern = 'matt';
my $text = 'Matt';
my $rep_text = 'Matthew';
my $pattern_opts = 'i';
print $text, "\n" if $text =~ s/(?$pattern_opts:$pattern)/$rep_text/;
更新以响应新的代码:您可以考虑使用的方法是这样的:
my ($orig, $patt, $rep, $flags) = qw(FooFooFoo foo bar ig);
my $make_replacement = $flags =~ s/g// ?
sub { $_[0] =~ s/(?$flags:$patt)/$rep/g } :
sub { $_[0] =~ s/(?$flags:$patt)/$rep/ }
;
if ( $make_replacement->($orig) ){
print $orig;
}
else {
print "Failed...";
}
其他提示
与-r "matt"
运行它,不-r "/matt/"
。你并不需要,并不能在事实上,在你的选项字符串供应格局的分隔符。该报价是在你qr
的分隔符。所以它实际上是寻找matt
与周围斜线,你正在运行的方式,这是不是你想要的。您正在尝试使用引号来告诉Perl来对待你的模式串喜欢它是源代码,但不幸的是,你不能这样做。
所有这些模式追加你做其他选项也将无法正常工作。你需要改变你编译正则表达式的方式,如果你想要做的一切。像这样的东西可能会为/i
和/s
做到这一点:
my $compd_pattern = qr/$pattern/ or die $@;
$compd_pattern = qr/$compd_pattern/i if $options{i};
$compd_pattern = qr/$compd_pattern/s if $options{s};
有关/g
则需要支持搜索的替代版本/替换。 /g
不是有效的改性剂,以qr//
。