我正在尝试编译一组替换正则表达式,但我不知道如何在我搁置的替换标量中延迟捕获变量的插值;这是一个简单的示例:
use strict;
use warnings;
my $from = "quick";
my $to = "zippy";
my $find = qr/${from} (?<a>(fox|dog))/;
my $repl = "$to $+{a}"; # Use of uninitialized value in concatenation (.) or string
my $s0 = "The quick fox...\n";
$s0 =~ s/${find}/${repl}/;
print($s0);
这不起作用,因为 repl 会立即插值并引发“在连接 (.) 或字符串中使用未初始化的值”
如果我使用非插值 '' 引号,它不会在实际替换中插值,因此我得到“The zippy $+{a}...”
是否有一个技巧可以留出包含捕获引用的替换标量?
最佳答案
您收到警告是因为您在执行匹配之前使用了 $+{a}
。 qr//
不执行任何匹配;它只是编译模式。执行匹配的是 s///
。
您可能想使用
my $repl = "$to \$+{a}";
但这只是输出
The zippy \$+{a}...
您可以使用以下内容:
my $find = qr/quick (?<a>fox|dog)/;
my $s0 = "The quick fox...\n";
$s0 =~ s/$find/zippy $+{a}/;
print($s0);
但这对替换表达式进行了硬编码。如果您希望此代码是动态的,那么您正在构建的是一个模板系统。
我不知道有任何模板系统具有您所需的特定语法。
如果您同意使用位置变量 ($1
) 而不是命名变量 ($+{a}
),则可以使用 String::Substitution .
use String::Substitution qw( sub_modify );
my $find = qr/quick (?<a>fox|dog)/; # Or simply qr/\Q$from\E (fox|dog)/
my $repl = "zippy \$1";
my $s0 = "The quick fox...\n";
sub_modify($s0, $find, $repl);
print($s0);
关于regex - 使用 Perl 中的命名捕获和预编译正则表达式进行替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62999444/