首页 > 解决方案 > 检查用变量制作的正则表达式

问题描述

sub make-regex {
    my $what's-in-the-box = rand > .5 ?? 'x' !! 'y';
    /$what's-in-the-box/
}

my $lol-who-knows = make-regex;
$lol-who-knows.gist.say;

您如何看待正则表达式(即xy)的内部结构?强制匹配不是解决方案。

标签: raku

解决方案


您如何看待正则表达式(即xy)的内部结构?

你:

  • 静态编译正则表达式。这样做将涉及使用 raku 编译器,即 Rakudo。

  • 动态评估正则表达式,以便$what's-in-the-box您的正则表达式中的变量被插值并变成xor y。这样做将涉及将正则表达式作为代码运行。这反过来意味着既使用 Rakudo 又使用Match对象调用者(或子类实例,或者可以想象的模拟对象等价物)运行正则表达式。

  • 查看生成的正则表达式。这样做将涉及使用编译器 (Rakudo) 工具链特定的内省或调试功能。

强制匹配不是解决方案。

如果您只是为了避免需要成功匹配,则可以在没有输入的情况下运行正则表达式:

say Match.new.&$lol-who-knows; # #<failed match>

但它必须运行,否则$what's-in-the-box变量不会变成xor y。您可能认为您可以通过编写一些模仿 raku 正则表达式构造/使用部分的东西来作弊,但有充分的理由认为这不会奏效[1]

然后,您必须在开始运行它之后和完成运行之前,使用 Rakudo 工具链功能查看它的内部结构。

正则表达式是一种方法

在 raku 中,aRegex是代码,是Method.

在您运行它之前,通过在比赛中使用它,该代码只是/$what's-in-the-box/(又名regex { $what's-in-the-box })。它相当于:

method {
  ...self should be a Match or a sub-class of it
  ...if self is not an instance, create a new one
  ...do matching -- compiler evaluates $what's-in-the-box during this
  ...return updated self / new instance
}

(要了解更多细节,请参阅Moritz 对 SO Can I change the slang inside a method?的回答。)

例程是一个闭包

您在名为make-regex. 编译器会发现您使用过的$what's-in-the-box内容,因此即使在make-regex闭包返回后仍会保留该变量。稍后,如果/当您的正则表达式运行时,该$what's-in-the-box变量将被其在正则表达式运行时的值替换。

脚注

[1]如果您尝试使用编译器进行最终运行,您会遇到很多巨大的复杂情况。即使像插值这样简单的东西也不是微不足道的。在 2020 年引用Jonathan Worthington 的话:

我想哦,我只是在构建 [a tool that's] 不是真正的编译器。我可以......有一个更简单的符号解析模型。最后事实证明,不,我真的做不到。这开始给我们带来一些问题。当我们将解析符号的方式与编译器中使用的相同算法和查找结构对齐时,突然间一切都变得简单多了。


推荐阅读