Jul*_*lio 14 regex rakudo regex-alternation raku
Raku 的正则表达式预计将匹配最长的令牌。
事实上,在这段代码中可以看到这种行为:
raku -e "'AA' ~~ m/A {say 1}|AA {say 2}/"
# 2
Run Code Online (Sandbox Code Playgroud)
但是,当文本在变量中时,它的工作方式似乎不同:
raku -e "my $a = 'A'; my $b = 'AA'; 'AA' ~~ m/$a {say 1}|$b {say 2}/"
# 1
Run Code Online (Sandbox Code Playgroud)
为什么他们以不同的方式工作?有没有办法使用变量并仍然匹配最长的令牌?
Jon*_*ton 13
这里有两件事在起作用。
第一个是“最长令牌”的含义。当存在交替(使用|
或通过使用正则proto
表达式隐含)时,提取每个分支的声明性前缀。声明性表示可以由有限状态机匹配的 Raku 正则表达式语言的子集。声明性前缀是通过采用正则表达式元素直到遇到非声明性元素来确定的。您可以阅读更多内容并在文档中找到更多参考。
要了解事情为什么会这样,绕一小段路可能会有所帮助。构建解析器的一种常见方法是编写一个分词器,它将输入文本分解为一系列“标记”,然后是一个解析器,从这些标记中识别出更大的(可能是递归的)结构。标记化通常使用有限状态机执行,因为它能够快速减少搜索空间。使用 Raku 语法,我们不会自己编写分词器;相反,它会自动从我们的语法中提取(更准确地说,每个交替点计算一个标记器)。
其次,Raku 正则表达式是主要 Raku 语言中的一种嵌套语言,在一次传递中对其进行解析并同时编译。(这与大多数语言不同,在大多数语言中,正则表达式作为我们传递字符串的库提供。)最长的标记计算发生在编译时。但是,变量是在运行时插入的。因此,正则表达式中的变量插值是非声明性的,因此不被视为最长标记匹配的一部分。