当trans方法与regex等正则表达式一起使用时/^/,它将挂起并且无法再返回!
for (-9, -6 ... 0, 2 , 4 ... 10).rotor( 2 => -1) {
.join(',').trans(/^/ => '[', /$/ => ')' ).say;
}
Run Code Online (Sandbox Code Playgroud)
我对它进行打印以打印以下内容:
[-9,-6)
[-6,-3)
[-3,0)
[0,2)
[2,4)
[4,6)
[6,8)
[8,10)
Run Code Online (Sandbox Code Playgroud)
但是它只是糟透了,似乎不再返回了。正如Raku博士所说:“用一个或多个字符替换一个或多个字符”。似乎trans必须消耗至少一个字符:
> '123abc345'.trans( /<?after 34> 5$/ => '-')
123abc34-
> '123abc345'.trans( /<?after 34> 5/ => '-')
123abc34-
> '123abc345'.trans( /<?after 345> $/ => '-')
123abc345
> '123abc345'.trans( /^ \d+ <( \w+ )> $/ => '-')
123-
Run Code Online (Sandbox Code Playgroud)
我同意它必须消耗一个角色。
\n\n来自我写过的文档trans:
\n\n\n如果左侧的匹配器之一是空字符串或正则表达式,并且没有其他匹配器在输入字符串中的给定位置匹配,则
\n.trans进入无限循环。
也来自该文档:
\n\n\n\n\n[此文档]可能是更新官方文档和/或清理相关规范测试和/或功能的一个步骤。
\n
虽然我发现了几个trans可能涉及错误的问题,但以上是我在文档中唯一明确确定的内容。(我把这个问题放在一个奇怪的地方。确实,文档组织有点奇怪。我想我当时已经厌倦了跨式工作,打算再次返回以取得进一步的进展,但忘记了直到你问你的问题为止。)
无论如何,我刚刚在 GH和rt上搜索了 rakudo 问题,并且两个队列中都没有匹配的错误。
\n\n我认为它需要一个错误报告,至少对于trans根本不使用任何正则表达式并且只有一个空字符串匹配器导致无限循环的情况。(零长度匹配正则表达式导致循环的情况可能是一个单独的错误,应该通过修改正则表达式引擎代码来修复。我对此不确定。)
无论哪种方式,如果您想提出问题,请链接到此 SO,以便人们也能接触到我的跨文档。
\n\n让我们从正则表达式开始/^/——匹配字符串的开头——使用非trans构造来确认它做了正确的事情:
my $foo = \'x\';\nsay $foo ~~ s/^/end/; # \xef\xbd\xa2\xef\xbd\xa3\nsay $foo; # endx\nRun Code Online (Sandbox Code Playgroud)\n\n所以/^/匹配;这是零长度匹配/捕获;该s///构造插入替换字符串。一切看起来都很好。
行为trans要复杂得多。这是一个严重“仪器化”的示例,其匹配模式与您的示例接近,并且也是 的一部分trans:
sub start-regex ($which,$/) {\n say "start regex $which, ++count = {++$count}, .pos = {$/.pos}"\n}\nsub end-regex ($which,$/) {\n say "end regex $which, .pos = {$/.pos}, matched = \'$/\' \\n"\n}\nsub replace ($which,$/) {\n say "regex $which replaces $/ at .pos = $/.pos()"; $which\n}\n\nmy $foo = \'x\';\nmy $count;\n\nsay $foo.trans:\n / { start-regex 1, $/ } ^ { end-regex 1, $/ } /\n => { replace 1, $/ },\n / { start-regex 2, $/ } . <?{ $count > 0 }> $ { end-regex 2, $/ } /\n => { replace 2, $/ }\nRun Code Online (Sandbox Code Playgroud)\n\n这显示:
\n\nstart regex 1, ++count = 1, .pos = 0\nend regex 1, .pos = 0, matched = \'\' \n\nstart regex 2, ++count = 2, .pos = 0\nend regex 2, .pos = 1, matched = \'x\' \n\nregex 2 replaces x at .pos = 1\nstart regex 2, ++count = 3, .pos = 0\nend regex 2, .pos = 1, matched = \'x\' \n\nstart regex 1, ++count = 4, .pos = 1\nstart regex 2, ++count = 5, .pos = 1\n2\nRun Code Online (Sandbox Code Playgroud)\n\n这就是它的作用:
\n\n调用并匹配第一个正则表达式。匹配的长度为零。
调用并匹配第二个正则表达式。匹配是一个字符。
确定第二个正则表达式更长,因此它获胜。于是打电话换人。
将位置重置为零并再次调用第二个正则表达式!我不知道为什么。它再次匹配,但替换不会被第二次调用。
最后,随着位置前进一位,它再次尝试两个正则表达式,但它们都无法匹配。
如果第二个正则表达式中的条件从 改为 ,$count > 0情况$count > 2就会大不相同。它进入一个无限循环,开始如下:
start regex 1, ++count = 1, .pos = 0\nend regex 1, .pos = 0, matched = \'\' \n\nstart regex 2, ++count = 2, .pos = 0\nstart regex 2, ++count = 3, .pos = 1\nregex 1 replaces at .pos = 0\nstart regex 1, ++count = 4, .pos = 0\nend regex 1, .pos = 0, matched = \'\' \n\nstart regex 1, ++count = 5, .pos = 0\nend regex 1, .pos = 0, matched = \'\' \n\nregex 1 replaces at .pos = 0\nstart regex 1, ++count = 6, .pos = 0\nRun Code Online (Sandbox Code Playgroud)\n\n这就是它的作用:
\n\n调用并匹配第一个正则表达式。匹配的长度为零。
调用第二个正则表达式。条件失败,因此不会结束它。
重置.pos为1(!?) 并再次调用第二个正则表达式!我不知道为什么。又失败了。
调用与第一个正则表达式对应的替换闭包。为什么?我认为trans逻辑是如果正则表达式的长度为零,则不接受它!
位置未提前,然后再次匹配第一个正则表达式。两次!并且没有尝试匹配第二个正则表达式。然后再次调用与第一个正则表达式替换相对应的替换闭包。
现在我们陷入了循环,重复最后一个要点!
非常奇怪的行为...
\n