それはかなり簡単です。Mojo::Collectionオブジェクト内のすべての興味深い要素を選択するだけで(これは、たとえばMojo::DOMのchildren
メソッドが行うことです)、そのコレクションを反復しながら、ある種のステートマシンのような一致を行うことができます。
おそらくこれを行うための最も魔法の方法
スカラーコンテキストでPerlの範囲演算子を使用することです:..
スカラー コンテキストでは、「..」はブール値を返します。演算子はフリップフロップのように双安定であり、sed、awk、およびさまざまなエディターの行範囲 (コンマ) 演算子をエミュレートします。各 ".." 演算子は、それを含むサブルーチンへの呼び出し間でも、独自のブール状態を維持します。左オペランドが false である限り、false です。左のオペランドが true になると、範囲演算子は右のオペランドが true になるまで true のままになり、その後、範囲演算子は再び false になります。次に範囲演算子が評価されるまで false になりません。
ここにある
簡単な例
#!/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 を使用しgrep
てコレクション オブジェクトをフィルタリングしています$yay
。真を探すため、指定された関数の戻り値のスカラー コンテキスト..
を作成し、演算子はフリップフロップのように動作します。要素を最初に見た後に true になり、h1
要素を最初に見た後に false になるため、その見出し間のh2
すべての行を、それ自体を含めて取得します。
Perl をある程度知っていて、任意のテストを一緒に使用できると思うので、..
これが問題の解決に役立つことを願っています!