1

我想确保变量被插值,因为它们在 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}用空值(如[]or ())填充正则表达式,但这感觉不像是一个合适的分隔符。

为了清楚起见:

  1. 我想扩展$bo为在第一个匹配项中bother获取字符串。/botherther/
  2. 我想在第二场比赛中再次扩展$bi->{bo}theget 。<bo><the><[r]ther>/botherther/
  3. 重要的是,为了这个上下文,我不在乎转义\Q\E我假设变量中永远没有元字符”

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

4

2 回答 2

2

主要有四种方式:

  • 使用/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. 施加小的运行时惩罚。
于 2019-12-15T12:12:33.770 回答
1

要将插值变量名称与其他文本分开,通常
是这样的${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 可以区分分隔符以获取
字符串中的变量表示法,它将对其进行插值。

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

于 2019-12-14T20:49:00.793 回答