Raku:一个线表达式可以从字符串中捕获组?

con*_*con 6 string raku

我因此从字符串中捕获一个数字:

my $n1;
if $string1 ~~ /(<[0..4]>)$/ {
    $n1 = $0;
} else {
    put "$string1 failed regex.";
    die;
}
Run Code Online (Sandbox Code Playgroud)

这是很多行,但是我可以在一行中复制和编辑字符串,因此:

my $string2 = $group2.subst(/<[0..4]>$/, '');
Run Code Online (Sandbox Code Playgroud)

我仍在学习raku / perl6,我浏览了https://docs.perl6.org/type/Str,看起来Raku不能做到这一点……但我不确定。

有没有一种方法可以像上面的第一个代码示例一样在一行中捕获子字符串?

我在脚本中反复执行此过程,这确实会缩短脚本

Jon*_*ton 10

可以使用解构绑定将匹配的一部分提取到变量中。对于给出的示例,我们可以像这样提取匹配的部分:

my ($n) := "abc123" ~~ /(<[1..4]>+)$/;
say $n;  # ?123?
Run Code Online (Sandbox Code Playgroud)

这将扩大到提取匹配的多个部分:

my ($s, $n) := "abc123" ~~ /(<[a..z]>+)(<[1..4]>+)$/;
say $s;  # ?abc?
say $n;  # ?123?
Run Code Online (Sandbox Code Playgroud)

在Raku中捕获的东西本身就是Match对象,但是也可以在解构中使用强制,以便将其变成整数:

my (Int() $n) := "abc123" ~~ /(<[1..4]>+)$/;
say $n;       # 123
say $n.WHAT;  # (Int)
Run Code Online (Sandbox Code Playgroud)

它甚至可以与命名的匹配项一起使用(此处有点虚假,但是如果您要进行子规则调用则非常方便):

my (:$s, :$n) := "abc123" ~~ /$<s>=(<[a..z]>+) $<n>=(<[1..4]>+)$/;
say $s;  # ?abc?
say $n;  # ?123?
Run Code Online (Sandbox Code Playgroud)

这样做的明显缺点是,如果匹配失败,则可以获取异常。幸运的是,这可以与结合使用if

if "abc123" ~~ /(<[a..z]>+)(<[1..4]>+)$/ -> ($s, $n) {
    say $s;
    say $n;
}
Run Code Online (Sandbox Code Playgroud)

语法相同,因为解构绑定实际上只是签名的应用。


Val*_*kas 7

也许.match是您想要的。

my $string1='4';
my $n2 = $string1.match(/(<[0..4]>)$/) // die 'error';
say $n2.values;
Run Code Online (Sandbox Code Playgroud)