我有以下脚本读取文件,然后根据行末</h1>
将其放入数组中。如何仅阅读<h1>
和</h1>
之间的内容?
这是我的剧本:
out_array = []
open('foo.html') do |f|
f.each('</h1>') do |record|
record.gsub!("\n", ' ')
out_array.push record
end
end
# print array
p out_array
这是我的HTML
</h1>
akwotdfg
<h1>
<h1>I am foo</h1>
<h1>
Stubborn quaz
</h1>
<h3>
iThis
is a reas
long one line shit
</h3>
<h1>I am foo</h1>
这是我的输出:
["</h1>", " akwotdfg <h1> <h1>I am foo</h1>", " <h1> Stubborn quaz </h1>", " <h3> iThis is a reas long one line shit </h3> <h1>I am foo</h1>", " "]
答案 0 :(得分:1)
请查看以下代码:
out_array = open('foo.html') do |f|
f.read.scan(/<h1>(.*)<\/h1>/)
end
puts out_array
执行结果:
I am foo
I am foo
更新了多行扫描:
out_array = open('tempdir/foo.html') do |f|
f.read.scan(/<h1>([^<]*?)<\/h1>/m)
end
out_array.map! {|e| e[0].strip}
p out_array
执行结果:
["I am foo", "Stubborn quaz", "I am foo"]
答案 1 :(得分:0)
不要使用正则表达式来处理HTML或XML。对于琐碎的内容,您可以管理它,但是您的代码可能会因其他人的出价而发生变化。
而是使用解析器,例如Nokogiri:
require 'nokogiri'
html = '
</h1>
akwotdfg
<h1>
<h1>I am foo</h1>
<h1>
Stubborn quaz
</h1>
<h3>
iThis
is a reas
long one line
</h3>
<h1>I am foo</h1>
'
doc = Nokogiri::HTML(html)
h1_contents = doc.search('h1').map(&:text)
puts h1_contents
哪个输出:
# >>
# >> I am foo
# >>
# >> Stubborn quaz
# >>
# >>
# >> iThis
# >> is a reas
# >> long one line
# >>
# >> I am foo
# >> I am foo
# >>
# >> Stubborn quaz
# >>
# >> I am foo
请注意,Nokogiri正在返回<h3>
块内的内容。这是正确/预期的行为,因为HTML格式不正确。 Nokogiri修复格式错误的HTML以试图帮助检索可用内容,但由于结束标记有许多可能的位置,Nokogiri会在最后一个语法正确的位置插入结束标记。人类早知道这样做,但这是试图提供帮助的软件。
这种情况要求您预处理HTML以使其正确。我正在使用一个简单的sub
来修复找到的第一个<h1>
:
doc = Nokogiri::HTML(html.sub(/^(<h1>)$/, '\1</h1>'))
h1_contents = doc.search('h1').map(&:text)
puts h1_contents
# >> I am foo
# >>
# >> Stubborn quaz
# >> I am foo