我在doc.perl6.org中看到了触发器的使用,请参阅下面的代码:
my $excerpt = q:to/END/;
Here's some unimportant text.
=begin code
This code block is what we're after.
We'll use 'ff' to get it.
=end code
More unimportant text.
=begin code
I want this line.
and this line as well.
HaHa
=end code
More unimport text.
=begin code
Let's to go home.
=end code
END
my @codelines = gather for $excerpt.lines {
take $_ if "=begin code" ff "=end code"
}
# this will print four lines, starting with "=begin code" and ending with
# "=end code"
.say for @codelines;
=begin code
This code block is what we're after.
We'll use 'ff' to get it.
=end code
=begin code
I want this line.
and this line as well.
HaHa
=end code
=begin code
Let's to go home.
=end code
Run Code Online (Sandbox Code Playgroud)
我想行之间保存=begin code和=end code成单独的阵列,像这样的:
['This code block is what we're after.', 'We'll use 'ff' to get it.']
['I want this line.', 'and this line as well.', 'HaHa']
['Let's to go home.']
Run Code Online (Sandbox Code Playgroud)
我知道语法可以做到这一点,但我想知道是否有一种更好的方式?
您需要指定不要包含匹配的值.您可以通过添加^到要排除的运算符的一侧来执行此操作.在这种情况下,它是运营商的两面.
您还需要收集值以将其组合在一起.在这种情况下最简单的方法是在匹配之间放置它.
(如果您希望包含端点,则需要更多考虑才能使其正确)
my @codelines = gather {
my @current;
for $excerpt.lines {
if "=begin code" ^ff^ "=end code" {
# collect the values between matches
push @current, $_;
} else {
# take the next value between matches
# don't bother if there wasn't any values matched
if @current {
# you must do something so that you aren't
# returning the same instance of the array
take @current.List;
@current = ();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果你需要结果是一个数组数组(可变).
if @current {
take @current;
@current := []; # bind it to a new array
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用do for共享相同迭代器的序列.
这是有效的,因为for它比实际上更加渴望map.
my $iterator = $excerpt.lines.iterator;
my @codelines = do for Seq.new($iterator) {
when "=begin code" {
do for Seq.new($iterator) {
last when "=end code";
$_<> # make sure it is decontainerized
}
}
# add this because `when` will return False if it doesn't match
default { Empty }
}
Run Code Online (Sandbox Code Playgroud)
map取一个序列并将其转换为另一个序列,但在尝试从序列中获取下一个值之前不会执行任何操作.
for立即开始迭代,只在你告诉它时停止.
因此map即使在单个线程上运行也会导致竞争条件,但for不会.