Raku 有一个有趣且令人兴奋的递归正则表达式符号:<~~>
。
因此在 REPL 中我们可以这样做:
[0] > 'hellohelloworldworld' ~~ m/ helloworld /;
「helloworld」
[1] > 'hellohelloworldworld' ~~ m/ hello <~~>? world /;
「hellohelloworldworld」
直接从 Raku Docs for Recursive Regexes中获取,我们可以捕获/计算各种嵌套级别:
~$ raku -pe '#acts like cat here' nest_test.txt
not nested
previous blank
nestA{1}
nestB{nestA{1}2}
nestC{nestB{nestA{1}2}3}
~$ raku -ne 'my $cnt = 0; say m:g/ \{ [ <( <-[{}]>* )> | <( <-[{}]>* <~~>*? <-[{}]>* )> ] \} {++$cnt} /, "\t $cnt -levels nested";' nest_test.txt
() 0 -levels nested
() 0 -levels nested
() 0 -levels nested
(「1」) 1 -levels nested
(「nestA{1}2」) 2 -levels nested
(「nestB{nestA{1}2}3」) 3 -levels nested
(上面,改为say
仅put
返回捕获的字符串)。
但是我最近在尝试解决Unix 和 Linux 问题时遇到了一个问题,即:如何限制递归?假设我们只想捕获以下内容nestB
。有没有办法使用<~~>
递归正则表达式语法来做到这一点?
~$ raku -ne 'my $cnt = 0; say m:g/ nestB \{ [ <( <-[{}]>* )> | <( <-[{}]>* <~~>*? <-[{}]>* )> ] \} {++$cnt} /, "\t $cnt -levels nested";' nest_test.txt
() 0 -levels nested
() 0 -levels nested
() 0 -levels nested
() 0 -levels nested
() 0 -levels nested
() 0 -levels nested
注意:上文我尝试使用 强制执行某种“节俭的递归行为” <~~>*?
。事实是<~~>
(标准递归符号),<~~>?
、<~~>*
和<~~>*?
都给出相同的结果(rakudo-moar-2024.09-01
)。