正则表达式中的 Perl 变量消歧

Perl variable disambiguation within regex

我想确保变量在 perl 正则表达式中被插入。宁愿避免绑定到 "ifs" 级联中的其他变量,这些变量在整个代码执行过程中很少需要该变量。我如何确保我使用了变量?

use strict;
use warnings FATAL => "all";

$_="botherther";

my $bo = "bother";
if (/^$bother$/) { # want to consider just $bo here!
  print("Undestood regex as /($bo)ther/.\n");
} else {
  print("Couldnt discern variable.\n");
}

my $bi = { bo => "the" };
if (/^bo$bi->{bo}[r]ther$/) { # now, $bi->{bo} only
  print("Discerned /bo($bi->{bo})[r]/\n");
} else {
  print("Couldnt discern variable.\n");
}

我找不到在正则表达式中正确包装变量的方法。当然,我可以 my $bi_resolved = $bi->{bo} 或用空值填充正则表达式(如 []()),但这感觉不像是合适的分隔符。

为清楚起见:

  1. 我想将 $bo 扩展为 bother 以获得第一个匹配项中的 /botherther/ 字符串。
  2. 我想将 $bi->{bo} 扩展为 the 以获得 <bo><the><[r]ther>,在第二场比赛中再次 /botherther/
  3. 重要说明,为了这个上下文,我不关心转义 \Q\E"I am assuming there's never metacharacters within the variables" .

我已经通过问题进行了搜索,阅读了文档,但找不到这个问题的答案。包装在 ${} 中对我不起作用(那是试图取消引用的东西)。因此,在搜索时我觉得我只是在错误的树上吠叫......简直令人难以置信,没有人需要在 perlmonks 或 Whosebug 周围问类似的问题。我可能只是在这里寻找错误的关键字。 :/

将内插变量名与其他文本分开通常是
做得像 ${name}

因此,部分代码示例变为

use strict;
use warnings;

$_="botherther";

my $bo = "bother";
if (/^${bo}ther$/) { # want to consider just $bo here!
  print("Undestood regex as /${bo}ther/.\n");
} else {
  print("Couldnt discern variable.\n");
}

测试内容的一个好方法是将其放入 qr// 然后打印出来:

my $rx = qr/^${bo}ther$/;
print $rx;

根据@choroba:

就正则表达式而言,变量似乎也可以包装
在一个没有修改的组中,应该涵盖所有情况。
这真的只是一个解析的东西。如果 Perl 可以区分定界符得到
字符串中的变量符号,它将对其进行插值。

喜欢(?:$bo)(?:$bi->{bo})
但它会被包裹在一个残差组中。

主要有四种方式:

  • 使用/x$bi{bo} [r]而不是$bi{bo}[r]
  • 在变量名周围使用大括号(${bo}ther 而不是 $bother
  • 转义下一个字符($bo\->[0] 而不是 $bo->[0]
  • 通过括号或其他方式隔离((?:$bi{bo})[r] 而不是 $bi{bo}[r][1]

就是说,如果您要插入文本(而不是正则表达式模式),无论如何您都应该使用 \Q$var\E,这样问题就没有意义了。

use strict;
use warnings FATAL => "all";

$_="botherther";

my $bo = "bother";
if (/^\Q$bo\Ether$/) { # want to consider just $bo here!
  print("Understood regex as /^botherther$/.\n");
} else {
  print("Couldn't discern variable.\n");
}

my $bi = { bo => "the" };
if (/^bo\Q$bi->{bo}\E[r]ther$/) { # now, $bi->{bo} only
  print("Discerned /^bothe[r]ther$/\n");
} else {
  print("Couldn't discern variable.\n");
}

感谢@ysth 的改进。


  1. 施加小的 运行 时间惩罚。