Perl Regex 'e' (eval) modifier with s///

后端 未结 3 538
眼角桃花
眼角桃花 2020-12-02 20:37

I\'m having a little trouble comprehending this simple use of the /e regex modifier.

my $var = \'testing\';
$_ = \'In this string we are $var the \"e\" modif         


        
相关标签:
3条回答
  • 2020-12-02 20:49

    It’s not exactly a “simple” question, so don’t beat yourself up.

    The issue is that with a single /e, the RHS is understood to be code whose eval’d result is used for the replacement.

    What is that RHS? It’s $1. If you evaluated $1, you find that contains the string $var. It does not contain the contents of said variable, just $ followed by a v followed by an a followed by an r.

    Therefore you must evaluate it twice, once to turn $1 into $var, then again to turn the previous result of $var into the string "testing". You do that by having the double ee modifier on the s operator.

    You can check this pretty easily by running it with one /e versus with two of them. Here’s a demo a both, plus a third way that uses symbolic dereferencing — which, because it references the package symbol table, works on package variables only.

    use v5.10;
    
    our $str = q(In this string we are $var the "e" modifier.);
    our $var = q(testing);
    
    V1: {
        local $_ = $str; 
        s/(\$\w+)/$1/e;
        say "version 1: ", $_;
    
    }
    
    V2: {
        local $_ = $str;
        s/(\$\w+)/$1/ee;
        say "version 2: ", $_;
    }
    
    V3: {
        no strict "refs";
        local $_ = $str;
        s/\$(\w+)/$$1/e;
        say "version 3: ", $_;
    }
    

    When run, that produces:

    version 1: In this string we are $var the "e" modifier.
    version 2: In this string we are testing the "e" modifier.
    version 3: In this string we are testing the "e" modifier.
    
    0 讨论(0)
  • 2020-12-02 21:10

    To be clear, the s//ee form is not modifying your regex pattern or regex interpretation at all. It is an optional treatment of the replacement side string after the regex is performed. (See PERLOP Regex Quote-like operators)

    The e or ee just get mixed into the PATTERN side regex options in the s/PATTERN/REPLACEMENT/msixpodualgcer form.

    From Perlop:

    Options are as with m// with the addition of the following replacement specific options:

    e Evaluate the right side as an expression.
    ee  Evaluate the right side as a string then eval the result.
    r   Return substitution and leave the original string untouched.
    

    You can see the same e vs ee type behavior in non regex situations, as this example shows:

    #!/usr/bin/perl 
    use warnings;
    use strict;
    
    my $var = "var's contents";
    my $str='"-> $var <-"';
    print eval('$str'), "\n";        # equivalent to s//e
    print eval(eval('$str')), "\n";  # equivalent to s//ee
    

    Output:

    "-> $var <-"
    -> var's contents <-
    
    0 讨论(0)
  • 2020-12-02 21:10

    Try the rename utility from the latest perl package with:

    rename -v 's/\b(\w)/uc($1)/eg' *
    

    Here, pattern \b find the word boundary, and the e modifier enables evaluation in the substitution, and g replace the all occurrence.

    You may also rename to camelCase with:

    rename -v 's/\b(\w)/uc($1)/eg' *
    rename -v 's/^(\w)/lc($1)/e' *
    rename -v 's/\s+//g' *
    
    0 讨论(0)
提交回复
热议问题