regex - 使用 Perl 中的命名捕获和预编译正则表达式进行替换

标签 regex perl

我正在尝试编译一组替换正则表达式,但我不知道如何在我搁置的替换标量中延迟捕获变量的插值;这是一个简单的示例:

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/

相关文章:

c# - 如何在 C# 中解析 OData $filter

perl - 在数组中如何使用perl检查列表元素的最大大小

perl - 剔除下限和上限之外的所有值的内置方法,perl数组

java - 在操作 MM/DD/YYYY 格式时,如何获取月份(破折号之前的所有 #)

php - 模板引擎-正则表达式,DOMDocument和xpath或其他内容?

javascript - 在 Javascript 中用正则表达式替换独立字符串

sql - DBD::CSV 和占位符

perl - 使用 Perl Net::MAC 模块处理无效 MAC 条目的错误

c++ - Perl 系统调用导致核心转储但 $?保持为零

regex - Powershell - 如何将使用正则表达式找到的字符串大写