如何将正则表达式作为参数传递给Perl 6中的子例程

时间:2017-10-27 21:24:55

标签: perl6

可能我做了一些完全错误的事情,但有没有办法使用子程序修改和组合regexes?下面的程序不会编译。

sub a(Regex $r1) {
  return rx/ <$r1> a /
}

my regex letter_b { b };

my $new = a(letter_b);
say $new;

2 个答案:

答案 0 :(得分:8)

查看Regex的文档,它说:

  

可以使用正则表达式声明符定义命名的regex,后跟花括号中的定义。由于任何正则表达式都Callable内省需要通过& - sigil进行引用。

my regex R { \N };
say &R.^name; # OUTPUT: «Regex␤»

此外,Grammar文档(对于概念,而不是类型),它更多地解释了这一点:

  

语法的主要成分是名为正则表达式。虽然Perl 6 Regexes的语法超出了本文档的范围,但 named 正则表达式具有特殊语法,类似于子例程定义:

my regex number { \d+ [ \. \d+ ]? }
     

在这种情况下,我们必须使用my关键字指定正则表达式的词法作用域,因为命名的正则表达式通常在语法中使用。

     

被命名为我们提供了在其他地方轻松重用正则表达式的优势:

say so "32.51" ~~ &number;                                    # OUTPUT: «True␤»
say so "15 + 4.5" ~~ / <number> \s* '+' \s* <number> /        # OUTPUT: «True␤»

因此,要将您的命名正则表达式作为参数传递到a子例程中,您只需在其前面加上&符号:

my $new = a(&letter_b);
#           ^
#  This is what you need!

say $new;
say so "ba" ~~ $new;         # OUTPUT: «True␤»
say so "ca" ~~ $new;         # OUTPUT: «False␤»

答案 1 :(得分:3)

要将函数称为第一类值,请在其前加上&

此外,鉴于P6已经知道<$r1>是正则表达式,因此无需编写$r1。所以:

sub a(Regex $r1) {
  return rx/ $r1 a /
}

my regex letter_b { b };

my $new = a(&letter_b);
say $new;                # rx/ $r1 a /
say 'ba' ~~ $new;        # 「ba」

您没有显示错误,但是......

a(letter_b) 调用 letter_b来获取其值。 (然后a将被调用,letter_b返回的值作为第一个参数传递给a。)

letter_b是正则表达式,

say Regex ~~ Method; # True

所有方法至少需要一个调用arg:

say &letter_b.signature; # (Mu $: *%_)

但你用零参数调用它。产量:

Too few positionals passed; expected 1 argument but got 0

我猜错了你的错误信息。