我有类似这样的html
<h1>My heading</h1>
<p class="class1">
<strong>SOMETHING</strong> INTERESTING (maybe not).
</p>
<div class="mydiv">
<p class="class2">
<a href="http://www.link.com">interesting link</a> </p>
<h2>Some other heading</h2>
h1 和 h2 之间的内容各不相同 - 我知道我可以在 Mojo::Dom 中使用 css 选择器来选择 h1 或 h2 或 p 标签的内容 - 但如何选择 h1 和 h2 之间的所有内容?或者更一般地说,任意两个给定标签集之间的所有内容?
这非常简单。您可以选择一个中所有有趣的元素Mojo::集合 http://mojolicio.us/perldoc/Mojo/Collection对象(这就是Mojo::DOM http://mojolicio.us/perldoc/Mojo/DOM's children http://mojolicio.us/perldoc/Mojo/DOM#children方法例如)并在迭代该集合时执行某种类似状态机的匹配。
可能是最神奇的方法
是使用Perl的范围运算符.. http://perldoc.perl.org/perlop.html#Range-Operators在标量上下文中:
在标量上下文中,“..”返回一个布尔值。该运算符是双稳态的,就像触发器一样,并模拟 sed、awk 和各种编辑器的行范围(逗号)运算符。每个“..”运算符都维护自己的布尔状态,即使在调用包含它的子例程时也是如此。只要它的左操作数为假,它就是假的。一旦左操作数为真,范围运算符将保持为真,直到右操作数为真,之后范围运算符再次变为假。直到下次计算范围运算符时它才会变为 false。
Here's a
简单的例子
#!/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>
Output
<h1>INTERESTING STARTS HERE</h1>
<strong>SOMETHING INTERESTING</strong>
<span>INTERESTING TOO</span>
<h2>END OF INTERESTING</h2>
解释
所以我使用 Mojo::Collection 的grep http://mojolicio.us/perldoc/Mojo/Collection#grep过滤集合对象$yay
。因为它寻找真理,所以它创造了一个标量上下文对于给定函数的返回值,所以..
运算符的作用类似于触发器。第一次看到后就变成真的了h1
元素并在第一次看到 a 后变为 falseh2
元素,这样你就可以得到所有行between那个头条新闻包括他们自己。
因为我认为你了解一些 Perl 并且你可以使用任意测试..
我希望这有助于解决您的问题!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)