使用 vi 屏幕编辑器,我会这样做
%s/^drop table .*/exec rename_table('&')/g
允许我重新格式化找到的字符串。我需要在Perl中做同样的事情。
我编写了一个模块,我将模式传递给$regexp
和替换$newtxt
字符串。
此模块
if ( $_ !~ /$regexp/ ) {
print FOUT;
}
else {
s/$regexp/$newtxt/g;
print FOUT;
}
我试过
perl_swap( '(drop table .*);' , 'echo $3;' )
希望找到的表名 - 第三个参数 - 将映射到$3
。
答案 0 :(得分:1)
你要求的是(大部分)不可能。 Perl不会特别处理替换字符串中的任何字符。
您可以做的是捕获(显式或隐式)匹配的文本,并使用替换部分中的一个特殊变量($1
,$2
,$&
等),但这只能起作用,因为替换部分是代码。在您的情况下,s/$regexp/$newtxt/g
,唯一的变量是$newtxt
,其内容未重新扫描以进一步扩展。
您可以通过将带有重载字符串化的对象传递为s/$regexp/$newtxt/g
来欺骗$newtxt
代码,但更改代码会更好(即更容易和更易维护)。事实上,现有的代码已经有点傻了:
if ($_ !~ /$regexp/)
{
print FOUT;
}
else
{
s/$regexp/$newtxt/g;
print FOUT;
}
可以简化为
s/$regexp/$newtxt/g;
print FOUT;
为了允许动态替换,自然界面是使用函数,而不是字符串:
s/$regexp/ $newtxt->() /eg;
这里/e
告诉Perl,替换部分将被解析为代码块,而不是带引号的字符串。这个电话看起来像是
perl_swap( 'drop table (.*);' , sub { "echo $1;" } );
$1
是第一个捕获组(
)
的内容。
另一方面,如果接口必须仅使用字符串,则需要进行更多的手动工作或使用为您执行此操作的模块。例如:
use Data::Munge qw(replace);
...
$_ = replace($_, $regexp, $newtxt, 'g');
这允许调用表单
perl_swap( 'drop table (.*);' , 'echo $1;' );
因为Data::Munge::replace
在替换字符串中显式扫描并展开$
序列,例如$1
。
答案 1 :(得分:1)
您正在寻找String::Substitution的gsub_modify
。
use String::Substitution qw( gsub_modify );
my $pat = 'drop table (.*);';
my $repl = 'echo $1;';
local $_ = 'drop table foo;';
gsub_modify($_, $pat, $repl);
say;
答案 2 :(得分:0)
我认为这会做你想要的。
#!/usr/bin/env perl
# always use these two
use strict;
use warnings;
# use autodie to automatically die on open errors
use autodie;
my $s = 'drop table FOO';
print "$s\n";
if( $s =~ s/^drop table (.*)/exec rename_table('&')/ ){
my $captured = $1;
$s =~ s/\&/$captured/;
}
print "$s\n";