rad*_*att 6 regex perl substitution qr-operator
我正在编写一个使用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
Run Code Online (Sandbox Code Playgroud)
当我使用-r"/ matt /" - i运行它,并在文本'matt'上输入替换文本'matthew'时,它会失败.为什么是这样?
编辑:
谢谢你们的答案!这真的非常有帮助.我将您的两个建议结合到问题的工作解决方案中.我必须以不同的方式处理/ 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
Run Code Online (Sandbox Code Playgroud)
FMc*_*FMc 11
正如混乱所指出的那样,你会遇到一些困难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/;
Run Code Online (Sandbox Code Playgroud)
更新以响应您的新代码:您可以考虑使用这样的方法:
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...";
}
Run Code Online (Sandbox Code Playgroud)
运行它-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};
Run Code Online (Sandbox Code Playgroud)
因为/g您需要支持搜索/替换的替代版本. /g不是有效的修饰符qr//.
| 归档时间: |
|
| 查看次数: |
9751 次 |
| 最近记录: |