8

如何在前瞻断言中使用捕获组?

这段代码:

say "ab" ~~ m/(a) <?before (b) > /;

返回:

「a」
 0 => 「a」

但我期待也能捕捉到'b'。

有没有办法这样做?

我不想将 'b' 留在前瞻之外,因为我不希望 'b' 成为比赛的一部分。

有没有办法捕获'b'但仍将其留在比赛之外?

笔记:

我尝试使用 Raku 的捕获标记,如下所示:

say "ab" ~~ m/<((a))> (b) /;

「a」
 0 => 「a」
 1 => 「b」

但这似乎不像我预期的那样工作,因为即使“b”被留在比赛之外,正则表达式已经处理了“b”。而且我也不想被处理。

例如:

say 'abab' ~~ m:g/(a)<?before b>|b/;

(「a」
    0 => 「a」
 「b」 
 「a」
    0 => 「a」
 「b」)

# Four matches (what I want)
 

say 'abab' ~~ m:g/<((a))>b|b/;

(「a」
    0 => 「a」 
 「a」
    0 => 「a」)

# Two matches
4

1 回答 1

7

有没有办法这样做?

不是真的,但有点。三件事合谋反对我们试图实现这一目标。

  1. Raku 正则表达式捕获匹配树。因此(a(b))导致一个位置捕获包含另一个位置捕获。我为什么要提这个?因为同样的事情也发生在类似的事情上before,它以一个正则表达式作为参数:传递给的正则表达式before得到它自己的Match对象。
  2. ?意味着“不要捕获”。我们可能会考虑把它丢到 get中,现在对象中<before (b)>确实有一个beforeMatch,这听起来很有希望,除了......
  3. before实际上并没有返回它在内部匹配的内容,而是一个零宽度的Match对象,否则如果我们确实忘记了,?我们最终会得到它不是一个前瞻。

如果我们能从Match前瞻内部救出这个物体就好了。好吧,我们可以!我们可以声明一个变量,然后将参数正则表达式的$/内部绑定before到其中:

say "ab" ~~ m/(a) :my $lookahead; <?before b {$lookahead = $/}> /;
say $lookahead;

这使:

「a」
 0 => 「a」
「b」

哪个有效,尽管不幸的是它不像普通捕获那样附加。没有办法做到这一点,尽管我们可以通过以下方式附加它make

say "ab" ~~ m/(a) :my $lookahead; <?before (b) {$lookahead = $0}> { make $lookahead } /;
say $/.made;

使用相同的输出,除了现在它将可靠地附加到从 回来的每个匹配对象上m:g,因此即使不漂亮,也会很健壮。

于 2020-11-18T21:58:10.793 回答