【发布时间】:2020-08-10 13:10:33
【问题描述】:
如题所示,$/ 和$¢ 有什么区别?它们似乎总是具有相同的值:
my $text = "Hello world";
$text ~~ /(\w+) { say $/.raku } (\w+)/;
$text ~~ /(\w+) { say $¢.raku } (\w+)/;
两者都会导致 Match 对象具有相同的值。使用其中一个的逻辑是什么?
【问题讨论】:
如题所示,$/ 和$¢ 有什么区别?它们似乎总是具有相同的值:
my $text = "Hello world";
$text ~~ /(\w+) { say $/.raku } (\w+)/;
$text ~~ /(\w+) { say $¢.raku } (\w+)/;
两者都会导致 Match 对象具有相同的值。使用其中一个的逻辑是什么?
【问题讨论】:
变量$/ 指的是最近的匹配,而变量$¢ 指的是最近的最外面的匹配。在像上面这样的大多数基本正则表达式中,这可能是相同的。但是从.raku 方法的输出可以看出,Match 对象可以包含其他Match 对象(这就是您使用$<foo> 或$1 进行捕获时得到的)。
假设我们有以下带有量化捕获的正则表达式
/ ab (cd { say $¢.from, " ", $¢.to } ) + /
如果我们匹配“abcdcdcd”,运行它会看到以下输出:
0 2
0 4
0 6
但如果我们从使用$¢ 更改为$/,我们会得到不同的结果:
2 2
4 4
6 6
(.to 似乎有点偏离的原因是它——和.pos——直到捕获块结束才更新。)
换句话说,$¢ 将始终引用您的最终匹配对象(即$final = $text ~~ $regex),因此您可以完全按照您的方式遍历正则表达式内部的复杂捕获树将在完成完整匹配之后因此在上面的示例中,您可以只使用 $¢[0] 来引用第一场比赛,$¢[1] 第二场比赛,等等。
在正则表达式代码块内,$/ 将引用最直接的匹配项。在上述情况下,这是 ( ) 内部的匹配,不知道其他匹配,也不知道匹配的原始开始:只是 ( ) 块的开始。所以给出一个更复杂的正则表达式:
/ a $<foo>=(b $<bar>=(c)+ )+ d /
我们可以通过说$¢<foo> 随时使用$¢ 访问所有foo 令牌。我们可以使用$¢<foo>[0]<bar> 访问给定foo 的bar 令牌。如果我们在foo的捕获中插入一个代码块,它将能够使用$<bar>或$/<bar>访问bar令牌,但它不能访问其他foos。
【讨论】:
$/ 和 $¢ 之间的主要区别是范围:后者只有在正则表达式内有一个值”来表示 $¢ 只是一个残留痕迹,就像 Cursor 一样。当我阅读您的答案时,我认为$¢ 将是我在my answer 的A possible Improvement? 部分中创建的$*TOP 到SO“为什么/如何在匹配中需要一个额外的变量具有捕获组的重复任意字符?”。但是我尝试用$¢ 替换$*TOP 失败了。你明白我在那个答案中的意思吗?你能做到吗?
$¢ 会为每个令牌更新,所以你必须在 TOP 令牌中说 $*TOP := $¢ 但这并不能消除对当然是$*TOP var。我同意能够参考顶级比赛真是太棒了。最终,问题仍然是您确定的问题:当位置/哈希匹配 post 到匹配对象时。当使用$¢(每个令牌)时,结果将根据定义在遇到其封闭的{ } 块时立即发布。
Binex 时,我发现在遇到匹配结果后立即发布匹配结果在计算上并没有变得更糟。在一天结束时,您正在推送/弹出到缓存列表/哈希,或者您正在推送/弹出到匹配的列表/哈希。但是,可能存在某种我不知道用于 LTM 的内部加速,这可能是它的核心({ } 出于 LTM 的目的终止了一个令牌,因此更有可能运行/tested 比 | 分组中的其余令牌)
$¢ 是动态的,当它不起作用时我感到很惊讶。但是一分钱现在下降了,因为它是词汇的,正如我可以猜到的那样,因为你使用了“最外层”这个词,并且,正如你所解释的,它是在每条规则的开头建立的。
$¢ 和$/ 绑定到同一个对象,即这个新的匹配对象,它将记录这个规则匹配和捕获的内容。然后,随着匹配的进行,$¢ 仍然绑定到这个整体匹配对象,而 $/ 每次创建新匹配对象时都会重新绑定,因此它始终对应于最新的匹配对象。对吗?