Regex 相当于`&;``的Perl“中的占位符”;六";编辑

Regex 相当于`&;``的Perl“中的占位符”;六";编辑,regex,perl,Regex,Perl,使用vi屏幕编辑器,我可以这样做 %s/^drop table .*/exec rename_table('&')/g 这允许我重新格式化找到的字符串。我需要在Perl中执行同样的操作 我已经编写了一个模块,向其中传递模式$regexp和替换$newtext字符串 这个模块有 if ( $_ !~ /$regexp/ ) { print FOUT; } else { s/$regexp/$newtxt/g; print FOUT; } 我试过了 perl_sw

使用vi屏幕编辑器,我可以这样做

%s/^drop table .*/exec rename_table('&')/g
这允许我重新格式化找到的字符串。我需要在Perl中执行同样的操作

我已经编写了一个模块,向其中传递模式
$regexp
和替换
$newtext
字符串

这个模块有

if ( $_ !~ /$regexp/ ) {
    print FOUT;
}
else {
    s/$regexp/$newtxt/g;
    print FOUT;
}
我试过了

perl_swap( '(drop table .*);' , 'echo $3;' )
希望找到的第三个参数表名映射到
$3

你的要求(大部分)是不可能的。Perl不专门处理替换字符串中的任何字符

您可以做的是捕获(显式或隐式)匹配的文本,并使用替换部分中的一个特殊变量(
$1
$2
$&
,等等),但这仅适用于替换部分是代码。在您的示例中,
s/$regexp/$newtext/g
,唯一的变量是
$newtext
,它的内容不会为进一步扩展而重新扫描

通过将重载字符串化的对象传递为
$newtext
,您可能能够欺骗
s/$regexp/$newtext/g
代码,但更改代码会更好(即更容易维护)。事实上,现有的代码已经有点傻了:

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;' );
因为显式扫描并展开替换字符串中的
$
序列,例如
$1

您正在查找的是的
gsub\u modify

use String::Substitution qw( gsub_modify );

my $pat = 'drop table (.*);';
my $repl = 'echo $1;';
local $_ = 'drop table foo;';
gsub_modify($_, $pat, $repl);
say;

我想这会满足你的要求

    #!/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";

vi
&
扩展到整个匹配字符串,包括
下拉表
。这不是您想要的。是的,perl代码很详细,但无法更改,调用语言也是自定义shell。脚本希望使用这些命令处理文件,以基本上替换它们;因此,vi中的“&”对我来说很好——我的示例只是越来越热衷于使用示例中的最后一个标记;我是说它很愚蠢,而且毫无理由地包含重复的代码。这和呼叫语言有什么关系?。。。说到冗长,代码奇怪地不冗长:
s/$regexp/$newtext/g;印刷字体
可以被编写成
$\ux=~s/$regexp/$newtext/g;打印金额$\如果你想完全明确。我以为你不赞成将“它不起作用”作为问题描述?我没有一个超出我评论范围的问题。是你写的“不起作用的解决方案”。@Borodin指的是。(我承认可能更清楚。)
autodie
在这里是多余的。如果
$s
已包含
&
任何位置,则此代码在语义上是错误的。在未确保前一个正则表达式匹配成功之前,切勿使用
$1
。您不需要在正则表达式中转义
&
autodie
使用strict相比没有更多冗余
使用警告您应该始终在代码中包含它们。您应该转义所有非字母数字字符,因为您不知道它们将来是否会用作元字符。我不同意autodie,但可以。至于(目前非特殊)非字母数字字符:它们不会用作正则表达式元字符,因为这会破坏所有现有程序。@melpomene关于
&
的说法是正确的,但我被
/g
修饰符愚弄了。模式被锚定到字符串的开头,因此多个
&
不是问题。这意味着
/g
修饰符是多余的。而且具有误导性。我已经更正了代码。