文件IO由分隔符读​​取?

时间:2013-11-26 02:51:29

标签: ruby file-io io

我有以下脚本读取文件,然后根据行末</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>", " "]

2 个答案:

答案 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