在 Ruby 中创建 HTML 解析器

Creating a HTML Parser in Ruby

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

问题描述:

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

<span style="background-color: blue; color: white">keyword</span>

您必须注意不要突出显示 HTML 中出现的字符串 标签。例如,如果关键字是 ``table'',您就不想标记 这个:

<table width="100%" border="0">

到目前为止我做了什么:

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>'

我不确定是什么导致了错误,可以使用一些指导来解决问题。我还想知道这个程序是否正朝着正确的方向前进作为编程问题的答案。我知道 Nokogiri 已经可以作为资源使用,但我希望不必使用它,除非它被认为是更好的选择。

I'm unsure what is causing the error and could use some guidance to fix the issue.

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

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
}

错误消息说:

    part4_program.rb:16:in `each': closed stream (IOError)

所以,发生的事情是您尝试使用 each 对已关闭的文件进行迭代。为什么是这样?好吧,现在代码缩进正确了,我们可以很容易地看到你 close both infile and outfile inside of the each 迭代器。这将导致各种问题:

  • 您关闭文件 ,而 each 仍在对其进行迭代。这将 "pull the rug out under each's feet",可以这么说。文件关闭时如何遍历文件?你应该幸运的是 each 检测到了这个并且你得到了一个很好的错误消息和一个干净的退出 - 从当前正在读取它的迭代器下关闭文件,可能导致更微妙和更难诊断的问题.
  • 即使 each 没有 中断因为你关闭了文件,你仍然调用 close 遍历迭代的时间,但你只能 close 一个文件一次,之后它已经关闭并且无法再次关闭。
  • 甚至 if 你可以多次关闭文件,你 writeoutfile,但你已经 close 在之前的迭代。您无法写入已关闭的文件。

I am also wondering if this program is heading in the right direction as an answer to the programming problem.

老实说,我什至不明白你在做什么。但是我要说"No",你的方向不对

这里只是一些破解代码的简单方法:

  • 如果关键词是table呢?
  • 如果<body></body>在同一行怎么办?
  • 如果关键字出现在行中 <body> 但在它之前怎么办?
  • 如果有人将其拼写为 <BODY><bOdY> 怎么办?
  • 可选标签呢?
  • 空结束标签呢?
  • 如果关键字出现在评论中怎么办?
  • 如果关键字出现在标签内怎么办?
  • 如果关键字出现在属性中怎么办?
  • 如果关键字出现在 <script> 元素内怎么办?
  • 如果关键字出现在 <style> 元素内怎么办?
  • 如果关键字出现在 <![CDATA[ 部分内怎么办?

I know Nokogiri is already available as a resource but I had hoped not to have to use it unless its thought to be a better option.

HTML 很复杂。真的很复杂。真的,真的复杂。除非你有一些 非常 重新发明轮子的充分理由,否则你应该重新使用别人已经完成的工作。甚至不用想太多,我就可以想出六种以上的方法来破坏你的解析器,而且我什至没有涉及到那些讨厌的极端情况。 (只是因为我 不知道 讨厌的极端情况,因为我 不需要 知道它们,因为其他人已经想出了它们全力以赴。)

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