Raku的正则表达式有望匹配最长的令牌。
实际上,此行为在以下代码中可见:
raku -e "'AA' ~~ m/A {say 1}|AA {say 2}/"
# 2
但是,当文本位于变量中时,它似乎无法以相同的方式工作:
raku -e "my $a = 'A'; my $b = 'AA'; 'AA' ~~ m/$a {say 1}|$b {say 2}/"
# 1
为什么它们以不同的方式工作?有没有办法使用变量并且仍然匹配最长的令牌?
这里有两件事在起作用。
第一个是“最长令牌”的含义。如果存在交替(使用|
或表示使用正则proto
表达式),则提取每个分支的声明性前缀。声明性是指Raku regex语言的子集,可以由有限状态机进行匹配。声明性前缀是通过使用正则表达式元素确定的,直到遇到非声明性元素为止。您可以阅读更多内容,并在docs中找到更多参考。
要了解为什么事情会这样,绕一小圈可能会有所帮助。构建解析器的一种常见方法是编写一个标记器,将输入文本分解为一系列“令牌”,然后使用一个解析器从那些标记中识别更大的(也许是递归的)结构。令牌化通常使用有限状态机执行,因为它能够快速缩减搜索空间。使用Raku语法,我们不会自己编写令牌生成器。取而代之的是,它会自动为我们从语法中提取出来(更准确地说,每个替换点都会计算出一个标记符)。
其次,Raku regexes是主要Raku语言中的一种嵌套语言,与之一次性解析并同时编译。(这与大多数语言不同,后者将正则表达式作为我们传递字符串的库来提供。)最长的令牌计算在编译时进行。但是,变量是在运行时插值的。因此,正则表达式中的变量插值是非声明性的,因此不被视为最长标记匹配的一部分。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句