首页 > 解决方案 > 在 Perl 6 中过滤匹配两个正则表达式的元素

问题描述

这里发生了一些我不太明白的事情。

> my @arr = <ac bc abc>
> @arr.grep: (( * ~~ /a/ ) && ( * ~~ /b/ ))
(bc abc)

> @arr.grep(* ~~ /a/).grep(* ~~ /b/)
(abc)

什么原因?

标签: raku

解决方案


你已经想出了完美的解决方案。

另一个是:

my @arr = <ac bc abc>
@arr.grep: { $_ ~~ /a/ && $_ ~~ /b/ }
(abc)

这个答案的其余部分只是解释了这个问题。这个问题中的问题是WhatStar &&WhatStar所涵盖的问题的更复杂版本。


如果它们是代码,则逻辑操作不会执行它们的参数。

所以{ $_ ~~ /a/ } && { $_ ~~ /b/ }返回{ $_ ~~ /b/ }

* ~~ /a/ && * ~~ /b/返回* ~~ /b/

同时,如果它是代码或正则表达式,grep 执行它的匹配器,所以这些都是相同的:

foo.grep: { $_ ~~ /.../ }
foo.grep:    * ~~ /.../;
foo.grep:         /.../;

Junctions的魔力

您的Junction解决方案似乎很自然。如果有人可以解释我在下面缺少的内容,我会很高兴。虽然我希望它能够工作,但它正在弯曲我的头来弄清楚它实际上是如何工作的,但我认为它类似于(但不完全是):

  • foo & bar变成Junction_foo bar

  • 尝试grep使用 aJunction作为参数进行调用。

  • 因为Junction在正常值Any层次结构之外,大多数例程没有匹配的签名。grep没有。

  • 当您调用例程并且没有相应的签名时,初始调度失败并且我们命中调度回退处理程序。可能是方法一。

  • 如果调度回退处理程序看到有Junction参数,那么它会提取 中的各个值Junction并启动逻辑并行的“线程”(目前从来没有真正的线程,但如果编译器认为这是一个好主意,则允许它们成为真正的线程)对应于这些值。因此,它对调用grep者的每个元素调用两次,并将结果输出回Junction与传入 相同类型的新元素Junction

  • 在布尔上下文中, aJunction折叠为单个结果。

  • (如果 aJunction在整体布尔上下文中,那么它可以(并行)根据结果短路。如果它是 anany并且有任何结果出现,True那么它可以取消其余的 - 或者如果它实际上正在做,则首先不做它们事情是按顺序进行的,目前总是如此。如果它是一个all并且任何结果出现,False它可以取消其余的。等等。)


推荐阅读