这很简单。您可以在Mojo::Collection对象中选择所有有趣的元素(例如,这就是Mojo::DOM的children
方法所做的)并在迭代该集合时进行某种状态机之类的匹配。
可能是最神奇的方法
是在标量上下文中使用 Perl 的范围运算符:..
在标量上下文中,“..”返回一个布尔值。该运算符是双稳态的,就像一个触发器,并模拟 sed、awk 和各种编辑器的行范围(逗号)运算符。每个“..”运算符都维护自己的布尔状态,即使在调用包含它的子例程时也是如此。只要它的左操作数是假的,它就是假的。一旦左操作数为真,范围运算符保持真,直到右操作数为真,之后范围运算符再次变为假。直到下一次评估范围运算符时它才会变为假。
这是一个
简单的例子
#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
use Mojo::DOM;
# slurp all DATA lines
my $dom = Mojo::DOM->new(do { local $/; <DATA> });
# select all children of <div id="yay"> into a Mojo::Collection
my $yay = $dom->at('#yay')->children;
# select interesting ('..' operator in scalar context: flip-flop)
my $interesting = $yay->grep(sub { my $e = shift;
$e->type eq 'h1' .. $e->type eq 'h2';
});
say $interesting->join("\n");
__DATA__
<div id="yay">
<span>This isn't interesting</span>
<h1>INTERESTING STARTS HERE</h1>
<strong>SOMETHING INTERESTING</strong>
<span>INTERESTING TOO</span>
<h2>END OF INTERESTING</h2>
<span>This isn't interesting</span>
</div>
输出
<h1>INTERESTING STARTS HERE</h1>
<strong>SOMETHING INTERESTING</strong>
<span>INTERESTING TOO</span>
<h2>END OF INTERESTING</h2>
解释
所以我使用 Mojo::Collection'sgrep
来过滤集合对象$yay
。因为它寻找真相,所以它为给定函数的返回值创建了一个标量上下文..
,因此运算符的作用就像一个触发器。它在第一次看到一个元素后变为真,在它第一次看到一个h1
元素后变为假,所以你会得到标题之间h2
的所有线条,包括它们自己。
因为我认为你知道一些 Perl,你可以一起使用任意测试,..
我希望这有助于解决你的问题!