在Ruby中创建HTML解析器

在Ruby中创建HTML解析器,ruby,html-parsing,Ruby,Html Parsing,我需要帮助解决我一直在研究的一个编程问题 问题描述: 用Ruby编写一个函数,接受HTML文档(字符串)和关键字(也是字符串)。函数将在元素之后查找HTML字符串中出现的所有关键字,除非关键字出现在HTML标记中,然后用标记将找到的字符串包围起来以“突出显示”关键字。比如说, <span style="background-color: blue; color: white">keyword</span> 关键字 您必须小心不要突出显示HTML中出现的字符串 标签。例

我需要帮助解决我一直在研究的一个编程问题

问题描述:

用Ruby编写一个函数,接受HTML文档(字符串)和关键字(也是字符串)。函数将在
元素之后查找HTML字符串中出现的所有关键字,除非关键字出现在HTML标记中,然后用标记将找到的字符串包围起来以“突出显示”关键字。比如说,

<span style="background-color: blue; color: white">keyword</span>
关键字
您必须小心不要突出显示HTML中出现的字符串 标签。例如,如果关键字是``表',则不希望标记 这:


到目前为止我所做的:

puts "Welcome to the HTML keyword highlighter!"
puts "Please Enter A Keyword: "
keyword = gets.chomp
canEdit = false 

infile = File.new("desktop/code.html", "r")
outfile = File.new("Result.html", "w")

infile.each{ |i| 
    if (i.include? "<body>")
        canEdit = true

    end

    if (i.include? "</body>")
        canEdit = false
    end

    if(canEdit == true)
        keyword.gsub(keyword, "<span style=\"background-color: yellow; color: black\">#{keyword}</span>")

    outfile.write i
end

outfile.close()
infile.close()
}
显示“欢迎使用HTML关键字荧光笔!”
放置“请输入关键字:”
关键字=gets.chomp
canEdit=false
infle=File.new(“desktop/code.html”,“r”)
outfile=File.new(“Result.html”,“w”)
每一个{i}
如果(i.包括?”)
canEdit=true
结束
如果(i.包括?”)
canEdit=false
结束
if(canEdit==true)
关键字.gsub(关键字“#{keyword}”)
outfile.write i
结束
outfile.close()
infle.close()
}
我当前收到的错误:

puts "Welcome to the HTML keyword highlighter!"
puts "Please Enter A Keyword: "
keyword = gets.chomp
canEdit = false 

infile = File.new("desktop/code.html", "r")
outfile = File.new("Result.html", "w")

infile.each{ |i| 
    if (i.include? "<body>")
        canEdit = true

    end

    if (i.include? "</body>")
        canEdit = false
    end

    if(canEdit == true)
        keyword.gsub(keyword, "<span style=\"background-color: yellow; color: black\">#{keyword}</span>")

    outfile.write i
end

outfile.close()
infile.close()
}
欢迎使用HTML关键字荧光笔

请输入关键字:

简单的

/Users/Eva/Desktop/Personal/part4_program.rb:16:in `each': closed stream (IOError)

from /Users/Eva/Desktop/Personal/part4_program.rb:16:in `<main>'
/Users/Eva/Desktop/Personal/part4_program.rb:16:in'each':封闭流(IOError)
from/Users/Eva/Desktop/Personal/part4_program.rb:16:in`'
我不确定是什么导致了错误,可以使用一些指导来解决问题。我还想知道,作为编程问题的答案,这个程序是否朝着正确的方向发展。我知道Nokogiri已经可以作为一种资源使用了,但我曾希望不必使用它,除非它被认为是一个更好的选择

我不确定是什么导致了错误,可以使用一些指导来解决问题

让我们首先对代码应用一些适当的格式,以便更清楚地了解发生了什么:

puts 'Welcome to the HTML keyword highlighter!'
puts 'Please Enter A Keyword: '
keyword = gets.chomp
can_edit = false 

infile = File.new('desktop/code.html', 'r')
outfile = File.new('Result.html', 'w')

infile.each {|i| 
  if i.include?('<body>')
    can_edit = true
  end

  if i.include?('</body>')
    can_edit = false
  end

  if can_edit
    keyword.gsub(keyword, %Q[<span style="background-color: yellow; color: black">#{keyword}</span>])
    outfile.write i
  end

  outfile.close
  infile.close
}
所以,现在的情况是,您尝试在一个关闭的文件上使用
每个
进行迭代。为什么会这样?好了,现在代码已正确缩进,我们可以很容易地看到您在
每个
迭代器的内部
关闭
填充和
输出文件
。这将导致各种问题:

  • 关闭文件时,每个仍在对其进行迭代。可以这么说,这将“在每个人的脚下拉出地毯”。当文件关闭时,它如何迭代文件?幸运的是,
    每个
    都检测到了这一点,并且得到了一条很好的错误消息和一个干净的退出–从当前正在读取的迭代器下关闭文件,可能会导致更微妙和更难诊断的问题
  • 即使
    each
    没有因为您从unter中关闭了文件而中断,您仍然会在每次迭代时调用
    close
    ,但您只能
    关闭一次文件,之后它已经关闭,无法再次关闭
  • 即使您可以多次关闭文件,您也可以将
    写入
    输出文件
    ,但在上一次迭代中,您已经
    关闭了它。无法写入已关闭的文件
我还想知道,作为编程问题的答案,这个程序是否朝着正确的方向发展

老实说,我一点也不明白你想做什么。但我要说“不”,你的方向不对

以下是破解代码的两种简单方法:

  • 如果关键字是
    ,该怎么办
  • 如果
    在同一行怎么办
  • 如果关键字作为
    出现在该行之前,该怎么办
  • 如果有人把它拼成
    怎么办
  • 可选标签呢
  • 空结束标记呢
  • 如果关键字出现在注释中怎么办
  • 如果关键字出现在标记中怎么办
  • 如果关键字出现在属性中怎么办
  • 如果关键字出现在
    元素中怎么办
  • 如果关键字出现在
    元素中怎么办
  • 如果关键字出现在
    部分中,该怎么办
我知道Nokogiri已经可以作为一种资源使用了,但我曾希望不必使用它,除非它被认为是一个更好的选择

HTML是复杂的。真的很复杂。真的,真的很复杂。除非你有很好的理由重新发明轮子,否则你应该重新使用别人已经做过的工作。甚至不用想太多,我就可以想出五六种以上的方法来破坏你的解析器,而且我甚至都没有进入到令人讨厌的角落。(只是因为我不知道那些令人讨厌的角落案例,因为我不需要知道它们,因为其他人已经把它们都弄明白了。)

编程的两个基本原则是抽象和重用。创建可重用的抽象并重用其他程序员的抽象

我不确定是什么导致了错误,可以使用一些指导来解决问题

让我们首先对代码应用一些适当的格式,以便更清楚地了解发生了什么:

puts 'Welcome to the HTML keyword highlighter!'
puts 'Please Enter A Keyword: '
keyword = gets.chomp
can_edit = false 

infile = File.new('desktop/code.html', 'r')
outfile = File.new('Result.html', 'w')

infile.each {|i| 
  if i.include?('<body>')
    can_edit = true
  end

  if i.include?('</body>')
    can_edit = false
  end

  if can_edit
    keyword.gsub(keyword, %Q[<span style="background-color: yellow; color: black">#{keyword}</span>])
    outfile.write i
  end

  outfile.close
  infile.close
}
所以,现在的情况是,您尝试在一个关闭的文件上使用
每个
进行迭代。为什么会这样?好了,现在代码已正确缩进,我们可以很容易地看到您在
每个
迭代器的内部
关闭
填充
输出文件
。这将导致各种问题:

  • 关闭文件时,每个仍在对其进行迭代。可以这么说,这将“在每个人的脚下拉出地毯”。当文件关闭时,它如何迭代文件?幸运的是,
    每个
    都检测到了这一点