我有以下代码解析HTML文本并修剪(或剥离)空的段落。它与String对象上的.strip
类似。
doc = Nokogiri::HTML::DocumentFragment.parse(html)
# repetition that I want to collapse
doc.css('p').each do |p|
if all_children_are_blank?(p)
p.remove
else
break
end
end
# repetition that I want to collapse
doc.css('p').reverse_each do |p|
if all_children_are_blank?(p)
p.remove
else
break
end
end
doc.to_s.strip
是否有一种更优雅的方法可以防止我用注释标记的代码被复制并遵守代码重用的原则?
以下是我的想法,但我对它不满意,想看看是否有更好的东西:
doc = Nokogiri::HTML::DocumentFragment.parse(html)
doc.css('p').each do |p|
if stop(p) then break end
end
doc.css('p').reverse_each do |p|
if stop(p) then break end
end
doc.to_s.strip
def self.stop(p)
if all_children_are_blank?(p)
p.remove
false
else
true
end
end
答案 0 :(得分:1)
如果我了解您要查找的内容,您希望以更简单的方式迭代您正在查看的元素,以便删除空白的p
元素。
这是一种直截了当的方式来折叠你所写的内容,而不是做很多不同的事情:
doc.tap do |d|
[:each, :reverse_each].each do |sym|
d.css("p").public_send(sym) do |p|
if blank_children?(p)
p.remove
else
break
end
end
end
end.to_s.strip
我还没有测试过,所以你可能需要调整一下。如果这是生产代码,我可能会将其分解为一个或多个方法调用,以便保持清晰。
答案 1 :(得分:1)
怎么样:
[*doc.css('p'), *doc.css('p').reverse].each do |p|
if stop(p) then break end
end
在这种情况下,splat运算符(“*”)将两个列表扩展为一个数组,元素按升序排列,然后按降序排列。然后你只是遍历整个小组。
编辑:
由于break
语句跳到一切结束,这将无法正常工作。因此,恕我直言,这样做的正确方法是将块分配给变量。你也可以消除stop
函数,因为你无论如何都要消除代码的重复:
remover = lambda do |p|
if all_children_are_blank? p
p.remove
else
break
end
end
doc.css('p').to_a.each(&remover).reverse_each(&remover)
希望这有帮助。
答案 2 :(得分:1)
可能是这样的:
puts "removing a top p" until stop(doc.at('p'))
puts "removing a bottom p" until stop(doc.search('p').last)
或只是:
puts "removing a p" until stop(doc.at('p')) && stop(doc.search('p').last)