编译正则表达式函数时出错,为什么我会遇到这个问题?
Error while compiling regex function, why am I getting this issue?
我的 RAKU 代码:
sub comments {
if ($DEBUG) { say "<filtering comments>\n"; }
my @filteredtitles = ();
# This loops through each track
for @tracks -> $title {
##########################
# LAB 1 TASK 2 #
##########################
## Add regex substitutions to remove superflous comments and all that follows them
## Assign to $_ with smartmatcher (~~)
##########################
$_ = $title;
if ($_) ~~ s:g:mrx/ .*<?[\(^.*]> / {
# Repeat for the other symbols
########################## End Task 2
# Add the edited $title to the new array of titles
@filteredtitles.push: $_;
}
}
# Updates @tracks
return @filteredtitles;
}
编译结果:
Error Compiling! Placeholder variable '@_' may not be used here because the surrounding block doesn't take a signature.
有什么明显的我遗漏的东西吗?感谢任何帮助。
这是我最终得到的结果:
my @tracks = <Foo Ba(r B^az>;
sub comments {
my @filteredtitles;
for @tracks -> $_ is copy {
s:g / <[\(^]> //;
@filteredtitles.push: $_;
}
return @filteredtitles;
}
is copy
确保由 for
循环设置的变量是可变的。
只需 s:g/...//;
即可删除不需要的字符。
没有人可以帮助您的一件事是您报告的错误。我目前认为您只是感到困惑。
下面是生成该错误的代码示例:
do { @_ }
但是您共享的代码不可能产生该错误,因为它要求您的代码中有一个 @_
变量,但实际上没有。
对于您可能会在 Whosebug 上报告的 未来 问题,我可以提供帮助的一种方法是鼓励您阅读并应用 Minimal Reproducible Example 中的指南。
虽然您的代码没有生成您所报告的错误,但如果您了解那里的一些 other 编译时间和 运行 时间错误,它可能会对您有所帮助在您分享的代码中。
Compile-time 错误:
您写了s:g:mrx
。这是无效的:Adverb mrx not allowed on substitution
.
您漏掉了 s///
的第三个斜线。这会导致混乱(见下文)。
有几个 run-time 错误,一旦我克服了 compile-time 错误。我只讨论一个,正则表达式:
.*<?[...]>
将 匹配 任何 sub-string 最终字符是 [...]
中列出的字符之一, 然后 捕获 除了 没有最后字符 的 sub-string。在 s:g/...//
替换的上下文中,这将去除普通字符(由 .*
捕获)但保留特殊字符。
这没有意义。
所以我从特殊字符模式中删除了 .*
和 ?
,将其从 <?[...]>
更改为(只是试图 匹配 对角色,但 不 捕获 如果它成功)只是 <[...]>
( also 尝试 match 匹配角色,但是,如果成功,does capture 也一样)。
最后一条评论是关于你犯的一个错误,这个错误很可能让你很困惑。
简而言之,s///
结构 必须 有 三个 个斜杠。
在您的问题中,您的代码格式为 s/.../
(或 s:g/.../
等),没有最后的斜线。如果您尝试编译此类代码,解析器会完全混淆,因为它会认为您只是在编写一个长替换字符串。
例如,如果您编写了以下代码:
if s/foo/ { say 'foo' }
if m/bar/ { say 'bar' }
就好像你写了:
if s/foo/ { say 'foo' }\nif m/...
这反过来意味着你会得到 compile-time 错误:
Missing block
------> if m/⏏bar/ { ... }
expecting any of:
block or pointy block
...
因为 Raku(do) 会将第二个和第三个 /
之间的部分解释为它解释为 s/.../.../
构造的替换双引号字符串,导致它在以下情况下成为 barf它遇到了 bar
.
因此,回顾一下,s///
构造需要 三个 个斜杠,而不是 两个 。
(我忽略了结构的语法变体,例如 s [...] = '...'
。)
因此,与@raiph 的回答相比,这是我的答案:
my @tracks = <Foo Ba(r B^az>.map: { S:g / <[\(^]> // };
仅此而已。没有其他的。让我们从里到外剖析它:
这部分:/ <[\(^]> /
是一个正则表达式,匹配一个字符,只要它是左括号(由\(
表示)或脱字符(^
).当它们进入尖角 brackets/square 括号组合时,这意味着它是一个 Enumerated character class.
然后: S
在文档的副词部分引入 non-destructive substitution, i.e., a quoting construct that will make regex-based substitutions over the topic variable $_
but will not modify it, just return its value with the modifications requested. In the code above, S:g
brings the adverb :g
or :global
(see the global adverb ) 播放,意思是(在替换的情况下) "please make as尽可能多的替换,最后的/
标记替换文本的结尾,因为它与第二个/
相邻,这意味着
S:g / <[\(^]> //
表示“请return$_
的内容,但修改为删除所有与正则表达式<[\(^]>
匹配的字符(替换为空字符串)"
在这一点上,我应该强调 Raku 中的正则表达式 真的 强大,并且阅读整个页面(可能best practices and gotchas 页面也是一个好主意。
接下来,.map
方法 documented here 将应用于任何 Iterable
(List
、Array
及其所有类似项)和将 return 基于 Iterable
的每个元素的序列,由传递给它的 Code
改变。所以,像这样:
@x.map({ S:g / foo /bar/ })
本质上意味着 "请 return Seq
@x
上每个项目的影响,通过将子字符串 foo
的任何外观替换为bar
"(@x
不会有任何改变)。 A nice place to start to learn about sequences and iterables would be here.
最后,我的one-liner
my @tracks = <Foo Ba(r B^az>.map: { S:g / <[\(^]> // };
可译为:
我有一个包含三个字符串元素的 List
Foo
Ba(r
B^az
(这将是您的“标题列表”的占位符)。获取该列表并生成第二个列表,其中包含其中的每个元素,但删除了字符“左括号”和“脱字符”的所有实例。
啊,并将结果存储在变量 @tracks
中(具有 my
范围)
我的 RAKU 代码:
sub comments {
if ($DEBUG) { say "<filtering comments>\n"; }
my @filteredtitles = ();
# This loops through each track
for @tracks -> $title {
##########################
# LAB 1 TASK 2 #
##########################
## Add regex substitutions to remove superflous comments and all that follows them
## Assign to $_ with smartmatcher (~~)
##########################
$_ = $title;
if ($_) ~~ s:g:mrx/ .*<?[\(^.*]> / {
# Repeat for the other symbols
########################## End Task 2
# Add the edited $title to the new array of titles
@filteredtitles.push: $_;
}
}
# Updates @tracks
return @filteredtitles;
}
编译结果: Error Compiling! Placeholder variable '@_' may not be used here because the surrounding block doesn't take a signature.
有什么明显的我遗漏的东西吗?感谢任何帮助。
这是我最终得到的结果:
my @tracks = <Foo Ba(r B^az>;
sub comments {
my @filteredtitles;
for @tracks -> $_ is copy {
s:g / <[\(^]> //;
@filteredtitles.push: $_;
}
return @filteredtitles;
}
is copy
确保由 for
循环设置的变量是可变的。
只需 s:g/...//;
即可删除不需要的字符。
没有人可以帮助您的一件事是您报告的错误。我目前认为您只是感到困惑。
下面是生成该错误的代码示例:
do { @_ }
但是您共享的代码不可能产生该错误,因为它要求您的代码中有一个 @_
变量,但实际上没有。
对于您可能会在 Whosebug 上报告的 未来 问题,我可以提供帮助的一种方法是鼓励您阅读并应用 Minimal Reproducible Example 中的指南。
虽然您的代码没有生成您所报告的错误,但如果您了解那里的一些 other 编译时间和 运行 时间错误,它可能会对您有所帮助在您分享的代码中。
Compile-time 错误:
您写了
s:g:mrx
。这是无效的:Adverb mrx not allowed on substitution
.您漏掉了
s///
的第三个斜线。这会导致混乱(见下文)。
有几个 run-time 错误,一旦我克服了 compile-time 错误。我只讨论一个,正则表达式:
.*<?[...]>
将 匹配 任何 sub-string 最终字符是[...]
中列出的字符之一, 然后 捕获 除了 没有最后字符 的 sub-string。在s:g/...//
替换的上下文中,这将去除普通字符(由.*
捕获)但保留特殊字符。这没有意义。
所以我从特殊字符模式中删除了
.*
和?
,将其从<?[...]>
更改为(只是试图 匹配 对角色,但 不 捕获 如果它成功)只是<[...]>
( also 尝试 match 匹配角色,但是,如果成功,does capture 也一样)。
最后一条评论是关于你犯的一个错误,这个错误很可能让你很困惑。
简而言之,s///
结构 必须 有 三个 个斜杠。
在您的问题中,您的代码格式为 s/.../
(或 s:g/.../
等),没有最后的斜线。如果您尝试编译此类代码,解析器会完全混淆,因为它会认为您只是在编写一个长替换字符串。
例如,如果您编写了以下代码:
if s/foo/ { say 'foo' }
if m/bar/ { say 'bar' }
就好像你写了:
if s/foo/ { say 'foo' }\nif m/...
这反过来意味着你会得到 compile-time 错误:
Missing block
------> if m/⏏bar/ { ... }
expecting any of:
block or pointy block
...
因为 Raku(do) 会将第二个和第三个 /
之间的部分解释为它解释为 s/.../.../
构造的替换双引号字符串,导致它在以下情况下成为 barf它遇到了 bar
.
因此,回顾一下,s///
构造需要 三个 个斜杠,而不是 两个 。
(我忽略了结构的语法变体,例如 s [...] = '...'
。)
因此,与@raiph 的回答相比,这是我的答案:
my @tracks = <Foo Ba(r B^az>.map: { S:g / <[\(^]> // };
仅此而已。没有其他的。让我们从里到外剖析它:
这部分:/ <[\(^]> /
是一个正则表达式,匹配一个字符,只要它是左括号(由\(
表示)或脱字符(^
).当它们进入尖角 brackets/square 括号组合时,这意味着它是一个 Enumerated character class.
然后: S
在文档的副词部分引入 non-destructive substitution, i.e., a quoting construct that will make regex-based substitutions over the topic variable $_
but will not modify it, just return its value with the modifications requested. In the code above, S:g
brings the adverb :g
or :global
(see the global adverb ) 播放,意思是(在替换的情况下) "please make as尽可能多的替换,最后的/
标记替换文本的结尾,因为它与第二个/
相邻,这意味着
S:g / <[\(^]> //
表示“请return$_
的内容,但修改为删除所有与正则表达式<[\(^]>
匹配的字符(替换为空字符串)"
在这一点上,我应该强调 Raku 中的正则表达式 真的 强大,并且阅读整个页面(可能best practices and gotchas 页面也是一个好主意。
接下来,.map
方法 documented here 将应用于任何 Iterable
(List
、Array
及其所有类似项)和将 return 基于 Iterable
的每个元素的序列,由传递给它的 Code
改变。所以,像这样:
@x.map({ S:g / foo /bar/ })
本质上意味着 "请 return Seq
@x
上每个项目的影响,通过将子字符串 foo
的任何外观替换为bar
"(@x
不会有任何改变)。 A nice place to start to learn about sequences and iterables would be here.
最后,我的one-liner
my @tracks = <Foo Ba(r B^az>.map: { S:g / <[\(^]> // };
可译为:
我有一个包含三个字符串元素的 List
Foo
Ba(r
B^az
(这将是您的“标题列表”的占位符)。获取该列表并生成第二个列表,其中包含其中的每个元素,但删除了字符“左括号”和“脱字符”的所有实例。
啊,并将结果存储在变量 @tracks
中(具有 my
范围)