在 Raku 中针对 <!before> 模式的无限族进行反匹配

lit*_*tle 9 grammar raku

我试图避免匹配字符串末尾的空格,同时仍然匹配单词中间的空格。

下面是一个正则表达式的例子,它匹配内的下划线x但不匹配最多三个尾随下划线。

say 'x_x___x________' ~~ /
[
| 'x'
| '_' <!before [
        | $ 
        | '_' <?before $> 
        | '_' <?before ['_' <?before $>]>
        | '_' <?before ['_' <?before ['_' <?before $>]>]>
        # ...
    ]>
]+
/;
Run Code Online (Sandbox Code Playgroud)

有没有办法构造...?隐含的模式的其余部分?

Bra*_*ert 6

辨别您的要求有点困难。


您可能正在寻找像这样简单的东西:

say 'x_x___x________' ~~ / 'x'+ % '_' ** 1..3 /
# ?x_x___x?
Run Code Online (Sandbox Code Playgroud)

或者

say 'x_x___x________' ~~ / 'x'+ % '_' ** 1..2 /
# ?x_x?
Run Code Online (Sandbox Code Playgroud)

或者

say 'x_x___x________' ~~ / 'x'+ % '_'+ /
# ?x_x___x?
Run Code Online (Sandbox Code Playgroud)


rai*_*iph 3

\n

避免匹配字符串末尾的空格,同时仍匹配单词中间的空格

\n
\n

根据布拉德的回答以及您对此的评论,如下所示:

\n
/ \\w+ % \\s+ /\n
Run Code Online (Sandbox Code Playgroud)\n
\n

我正在寻找的是一种匹配以已知模式结尾的任意长流的方法

\n
\n

根据@user0721090601对你的问题的评论,以及@p6steve答案的变体,如下所示:

\n
/ \\w+ % \\s+ )> \\s* $ /\n
Run Code Online (Sandbox Code Playgroud)\n

捕获)>标记标记捕获结束的位置。

\n

您可以在该标记的左侧和右侧使用任意图案。

\n
\n

<!before>无限的图案族

\n
\n

推广到任何类型的无限系列模式,无论它们是否为零宽度,正则表达式中最自然的解决方案是使用任何开放式标准量词进行迭代。例如,\\s+对于一个或多个空白字符。[1] [2]

\n
\n

有没有办法构建 隐含的模式的其余部分...

\n
\n

我将其概括为“Raku 正则表达式中是否有一种方法可以匹配理论上可以被计算机程序识别的某些任意模式?”

\n

答案总是“是”

\n
    \n
  • 虽然 Raku 规则/正则表达式可能看起来像传统的正则表达式,但它们实际上是嵌入在您最终拥有完全控制权的任意程序中的任意函数。

    \n
  • \n
  • 规则具有任意读取权限来捕获状态。[3]

    \n
  • \n
  • 规则可以进行任意图灵完备计算。[4]

    \n
  • \n
  • 规则/正则表达式的集合可以任意使用输入并驱动解析/匹配状态,即可以实现任何解析器。

    \n
  • \n
\n

简而言之,如果它可以被任何编程语言编写的任何程序匹配/解析,那么它就可以使用 Raku 规则/正则表达式进行匹配/解析。

\n

脚注

\n

[1]如果您使用开放式量词,则需要确保每次匹配迭代/递归要么消耗至少一个字符,要么失败,以便避免无限循环。例如,*即使它限定的模式不匹配,量词也会成功,因此请注意,这不会导致无限循环。

\n

[2]鉴于您编写示例的方式,也许您对递归而不是迭代感到好奇。可以说,这也很容易做到。[1]

\n

[3]在 Raku 规则中,捕获形成层次结构。有两个特殊变量跟踪此层次结构的两个关键级别的捕获状态:

\n
    \n
  • $\xc2\xa2是最内层封闭整体捕获的捕获状态。将其视为类似于由函数调用堆栈中的当前函数调用构造的返回值。

    \n
  • \n
  • $/是最内层封闭捕获的捕获状态。将其视为类似于由函数内的特定代码块构造的值。

    \n
  • \n
\n

例如:

\n
\'123\' ~~ / 1* ( 2* { print "$\xc2\xa2 $/" } ) 3* { print "$\xc2\xa2 $/" } / ; # 1 2123 123\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  • 总体/ ... /类似于普通的函数调用。第一个1和第一个123输出显示了整个正则表达式捕获的内容。

    \n
  • \n
  • ( ... )为正则表达式的一部分设置了内部捕获。它的内部2* { print "$\xc2\xa2 $/" }类似于一个代码块。显示2了它所捕获的内容。

    \n
  • \n
  • 最终123表明,在正则表达式的顶层,$/$\xc2\xa2具有相同的值。

    \n
  • \n
\n

[4]例如,上面脚注 3 中的代码在{ ... }块内包含任意代码。更普遍:

\n
    \n
  • 规则可以递归调用;

    \n
  • \n
  • 规则可以有完整的签名并传递参数;

    \n
  • \n
  • 规则可以包含任意代码;

    \n
  • \n
  • 规则可以使用多种调度语义来进行解析。值得注意的是,这可以包括基于最长匹配长度的解析。

    \n
  • \n
\n