Passing a regex substitution as a variable in Perl?

后端 未结 9 1830
青春惊慌失措
青春惊慌失措 2020-12-13 06:45

I need to pass a regex substitution as a variable:

sub proc {
    my $pattern = shift;
    my $txt = \"foo baz\";

    $txt =~ $pattern;
}

my $pattern = \'s         


        
相关标签:
9条回答
  • 2020-12-13 07:36

    I have an extremely simple script for mass file renaming that employs this trick :

    #!/opt/local/bin/perl
    sub oops { die "Usage : sednames s/old/new [files ..]\n"; }
    oops if ($#ARGV < 0);
    
    $regex = eval 'sub { $_ = $_[0]; ' . shift(@ARGV) . '; return $_; }';
    sub regex_rename { foreach (<$_[0]>) {
        rename("$_", &$regex($_));
    } }
    
    if ($#ARGV < 0) {  regex_rename("*");  }
    else {  regex_rename(@ARGV);  }
    

    Any perl command that modifies $_ like s/old/new could be employed to modify the files.

    I decided upon using eval so that the regular expression only needed to be compiled once. There is some wonkiness with eval and $_ that prevented me from using simply :

    eval 'sub { ' . shift(@ARGV) . ' }';
    

    although this &$regex certainly does modify $_; requiring the "$_" to evaluate $_ before calling rename. Yes, eval is quite fragile, like everyone else said.

    0 讨论(0)
  • 2020-12-13 07:38

    You're right - you were very close:

    eval('$txt =~ ' . "$pattern;");
    
    0 讨论(0)
  • 2020-12-13 07:46

    I found a probably better way to do it:

    sub proc {
        my ($pattern, $replacement) = @_;
        my $txt = "foo baz";
    
        $txt =~ s/$pattern/$replacement/g;  # This substitution is global.
    }
    
    my $pattern = qr/foo/;  # qr means the regex is pre-compiled.
    my $replacement = 'bar';
    
    proc($pattern, $replacement);
    

    If the flags of the substitution have to be variable, you can use this:

    sub proc {
        my ($pattern, $replacement, $flags) = @_;
        my $txt = "foo baz";
    
        eval('$txt =~ s/$pattern/$replacement/' . $flags);
    }
    
    proc(qr/foo/, 'bar', 'g');
    

    Please note that you don't need to escape / in the replacement string.

    0 讨论(0)
提交回复
热议问题