gpt4 book ai didi

raku - trans 函数在使用单个 `^` 或 `$` 时永远挂起

转载 作者:行者123 更新时间:2023-12-04 19:25:45 26 4
gpt4 key购买 nike

trans方法与正则表达式一起使用,例如 /^/ ,挂了,再也回不去了!

for (-9, -6 ... 0, 2 , 4 ... 10).rotor( 2 => -1) {
.join(',').trans(/^/ => '[', /$/ => ')' ).say;
}

我期望它打印出以下内容:
[-9,-6)
[-6,-3)
[-3,0)
[0,2)
[2,4)
[4,6)
[6,8)
[8,10)

但它只是变得很糟糕,似乎不会再回来了。如 Raku doc 说,“用一个或多个字符替换一个或多个字符”。看来 trans必须至少消耗一个字符:
> '123abc345'.trans( /<?after 34> 5$/ => '-')
123abc34-
> '123abc345'.trans( /<?after 34> 5/ => '-')
123abc34-
> '123abc345'.trans( /<?after 345> $/ => '-')
123abc345

> '123abc345'.trans( /^ \d+ <( \w+ )> $/ => '-')
123-

最佳答案

我同意它必须消耗一个字符。

来自 a doc I've written on trans :

If one of the matchers on the left hand side is a null string or regex, and no other matchers match at a given position in the input string then .trans goes into an infinite loop.



同样来自该文档:

[this doc] may be a step toward updating the official doc and/or cleaning up the relevant spec tests and/or functionality.



虽然我发现 trans 有几个问题这可能涉及错误,以上是我在文档中明确确定的唯一内容。 (我把我提到的这个问题放在了一个奇怪的地方。确实文档组织有点奇怪。我想我当时厌倦了反式工作,并打算再次返回以取得进一步进展而忘记了直到你刚刚问了你的问题。)

反正我只是 searched rakudo issues on GHrt并且两个队列中都没有匹配的错误。

我认为它值得一个错误报告,至少对于 trans 的情况。根本不使用任何正则表达式,只有一个导致无限循环的空字符串匹配器。 (零长度匹配正则表达式导致循环的场景可能是一个单独的错误,应该通过修改正则表达式引擎代码来修复。我不确定。)

无论哪种方式,如果您想提交问题,请链接到此 SO,以便人们也能接触到我的跨文档。

探索您的示例的变体

让我们从正则表达式开始 /^/ -- 匹配字符串的开头 -- 使用非 trans构造以确认它做正确的事情:
my $foo = 'x';
say $foo ~~ s/^/end/; # 「」
say $foo; # endx

所以 /^/火柴;这是一个零长度匹配/捕获; s///构造插入替换字符串。一切似乎都很好。
trans行为要复杂得多。这是一个严重“仪表化”的示例,其匹配模式与您的示例很接近,并且也是 trans 的一部分:
sub start-regex ($which,$/) {
say "start regex $which, ++count = {++$count}, .pos = {$/.pos}"
}
sub end-regex ($which,$/) {
say "end regex $which, .pos = {$/.pos}, matched = '$/' \n"
}
sub replace ($which,$/) {
say "regex $which replaces $/ at .pos = $/.pos()"; $which
}

my $foo = 'x';
my $count;

say $foo.trans:
/ { start-regex 1, $/ } ^ { end-regex 1, $/ } /
=> { replace 1, $/ },
/ { start-regex 2, $/ } . <?{ $count > 0 }> $ { end-regex 2, $/ } /
=> { replace 2, $/ }

这显示:
start regex 1, ++count = 1, .pos = 0
end regex 1, .pos = 0, matched = ''

start regex 2, ++count = 2, .pos = 0
end regex 2, .pos = 1, matched = 'x'

regex 2 replaces x at .pos = 1
start regex 2, ++count = 3, .pos = 0
end regex 2, .pos = 1, matched = 'x'

start regex 1, ++count = 4, .pos = 1
start regex 2, ++count = 5, .pos = 1
2

这就是它的作用:
  • 调用并匹配第一个正则表达式。匹配长度为零。
  • 调用并匹配第二个正则表达式。匹配是一个字符。
  • 决定第二个正则表达式更长,所以它赢了。所以叫换人。
  • 将位置重置为零并再次调用第二个正则表达式!我不知道为什么。它再次匹配,但不会第二次调用替换。
  • 最后,随着位置现在前进 1,它再次尝试两个正则表达式,但它们都无法匹配。


  • 如果第二个正则表达式中的条件从 $count > 0 改变至 $count > 2事情变得非常不同。它进入一个无限循环,像这样开始:
    start regex 1, ++count = 1, .pos = 0
    end regex 1, .pos = 0, matched = ''

    start regex 2, ++count = 2, .pos = 0
    start regex 2, ++count = 3, .pos = 1
    regex 1 replaces at .pos = 0
    start regex 1, ++count = 4, .pos = 0
    end regex 1, .pos = 0, matched = ''

    start regex 1, ++count = 5, .pos = 0
    end regex 1, .pos = 0, matched = ''

    regex 1 replaces at .pos = 0
    start regex 1, ++count = 6, .pos = 0

    这就是它的作用:
  • 调用并匹配第一个正则表达式。匹配长度为零。
  • 调用第二个正则表达式。条件失败所以它不会结束它。
  • 重置 .pos1 (!?) 并再次调用第二个正则表达式!我不知道为什么。它又失败了。
  • 调用对应于第一个正则表达式的替换闭包。为什么?我以为trans逻辑是不接受长度为零的正则表达式!
  • 位置没有前进,然后再次匹配第一个正则表达式。两次!并且没有尝试匹配第二个正则表达式。然后再次调用与第一个正则表达式替换对应的替换闭包。
  • 现在我们陷入了一个循环,重复最后一个要点!

  • 很奇怪的行为...

    关于raku - trans 函数在使用单个 `^` 或 `$` 时永远挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57660797/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com