Home > Back-end >  Regex Group: $1 in a string before replacement happens
Regex Group: $1 in a string before replacement happens

Time:11-20

I have the following code, which replaces a string with a part of it using $1:

my $string = "abcd1234";
print "$string\n";
    
$string =~ s/c(d1)2/<found: $1>/; 
print "$string\n";

Output:

abcd1234
ab<found: d1>34

Now I want to have variables, which contain the condition and the replacement. But if I do it like this, an error occurs:

my $string = "abcd1234";
print "$string\n";
    
my $cond = qr/c(d1)2/;
my $rule = "<found: $1>";
    
$string =~ s/$cond/$rule/; 
print "$string\n";

Output:

Use of uninitialized value $1 in concatenation (.) or string
abcd1234
ab<found: >34

I get, that $1 isn't existing in the line, where $rule is defined. But how can put a placeholder there?

CodePudding user response:

You can use sub_modify from String::Substitution:

use String::Substitution qw(sub_modify);

my $string = "abcd1234";
print "$string\n";
    
my $cond = qr/c(d1)2/;
my $rule = '<found: $1>';   # Single quotes!
    
sub_modify($string, $cond, $rule);
print "$string\n";

For completeness, note that it's also possible to do this using s/// with the /ee modifier. However, you shouldn't use it, as it can lead to security issues and various bugs.

CodePudding user response:

You can't delay the interpretation of a variable within a quoted string like that. $1 is substituted as soon as the line is executed.

To do what you seem to want, you would create a sprintf template and execute it in the replacement part of the substitution with the /e flag.

my $string = "abcd1234";
print "$string\n";

my $cond = qr/c(d1)2/;
my $replacement_fmt= "<found: %s>";

$string =~ s/$cond/sprintf($replacement_fmt, $1)/e; 
print "$string\n";

## ab<found: d1>34

  • Related