简体   繁体   English

如何在特定行或特定单词之后将文本插入文本文件?

[英]How to insert text into a text file on a specific line or after a specific word?

I need to create a method that will insert the values passed to it into the body of a index.html file immediately after the first <body> .我需要创建一个方法,将传递给它的值插入到 index.html 文件的正文中,紧跟在第一个<body>之后。

I have the code:我有代码:

class New_class

  def status(sourse, hp, sleep)

    @sourse = sourse

    File.open(@sourse, 'a'){ |file| file.puts  hp, sleep }

  end
end

tamgem = New_class.new

tamgem.status("index.html", 20, 20)

How can I make sure the numbers that I pass to this method are inserted into the body of the HTML document?如何确保传递给此方法的数字插入到 HTML 文档的正文中? Also, please note that this is a only Ruby, not Rails.另外,请注意,这只是 Ruby,不是 Rails。

You can make a method like this:您可以制作这样的方法:

def write_after_body(original_file, new_file, *new_content)
  File.open(new_file, 'w') do |file|
    IO.foreach(original_file) do |line|
      file.write(line)
      if line.include? '<body>'
        file.write(*new_content)
      end
    end
  end
end

It will leave the original file unchanged and create a new file with the changes you want because reading and writing from and to the same file at the same time isn't really a good idea.它将保持原始文件不变,并使用您想要的更改创建一个新文件,因为同时读取和写入同一个文件并不是一个好主意。 Calling the method like this:像这样调用方法:

write_after_body("index.html", "new_index.html", 20," ", 20)

Will copy all the content from the original file index.html to the new file new_index.html and also add 20 , " " and 20 to a new line after the <body> tag.将原始文件index.html中的所有内容复制到新文件new_index.html中,并在<body>标记后的新行中添加20" "20 After that, if you're happy with the results you can delete/move the old file and rename the new file.之后,如果您对结果感到满意,您可以删除/移动旧文件并重命名新文件。

Parsing HTML with regular expressions or any other primitive means like StringScanner is seldom a good idea .用正则表达式或任何其他原始方法(如 StringScanner)解析 HTML很少是一个好主意 Instead use a HTML parser ( nokogiri ) that actually understands HTML.而是使用实际理解 HTML 的 HTML 解析器 ( nokogiri )。

require 'nokogiri'
@doc = Nokogiri::HTML('<html><body></body></html>')
@doc.at('body').add_child('<h1>Hello World</h1>')
@doc.to_html
# => "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body><h1>Hello World</h1></body></html>\n"

Ruby has a built-in class called StringScanner , which can be used as a convenient way to find a position of some pattern inside of a string. Ruby 有一个内置的 class 称为StringScanner ,它可以作为一种方便的方法来查找字符串中某些模式的 position。

Why could this be useful in your case?为什么这对您的情况有用? You can try to find the index of the first character after the <body> tag.您可以尝试查找<body>标签后的第一个字符的索引。

Knowing that index, you can easily insert a substring into the correct place in your HTML.知道该索引后,您可以轻松地将 substring 插入 HTML 的正确位置。

Here is an example:这是一个例子:

<!-- index.html -->

<!DOCTYPE html>
<html>
<head>
  <title>Page Title</title>
</head>
<body>
  <h1>This is a Heading</h1>
  <p>This is a paragraph</p>
</body>
</html>
# Ruby script in the same folder as `index.html`.

# Library where StringScanner is located.
require 'strscan'

# Read all content of `index.html` and store it into a variable.
html = File.read('index.html')

# Create the StringScanner instance.
scanner = StringScanner.new(html)

# Then you are scanning your HTML string until the first occurence of the <body> tag.
scanner.scan_until(/<body>/)

# If your search is successful,
# then the scan pointer position will be just beyond the last character of the match.
# 
# In other words,
# the scan pointer position will be the index of the first character after `<body>` tag.
index = scanner.pos

# Simple insert
updated_html = html.insert(index, "\nHello")

# Write updated content to `index.html`.
File.write('index.html', updated_html)

So, probably your class will look like the following:因此,您的 class 可能如下所示:

require 'strscan'

class New_class
  def status(source, hp, sleep)
    html = File.read(source)

    scanner = StringScanner.new(html)

    scanner.scan_until(/<body>/)

    index = scanner.pos

    updated_html = html.insert(index, "#{hp} #{sleep}")

    File.write(source, updated_html)
  end
end

tamgem = New_class.new

tamgem.status("index.html", 20, 20)

As a last note: If you don't have any special requirements, please use CamelCase for class names as it is suggested by the majority of Ruby style guides.最后一点:如果您没有任何特殊要求,请使用 CamelCase 作为 class 名称,因为大多数 Ruby 样式指南都建议使用 CamelCase。 Here are some examples: Rubocop , Airbnb .以下是一些示例: RubocopAirbnb

Sources:资料来源:

  1. StringScanner 字符串扫描仪
  2. String#insert 字符串#插入
  3. File.read文件读取
  4. File.write文件写入
  5. CamelCase Classes by Rubocop Rubocop 的 CamelCase 类
  6. CamelCase Classes by Airbnb Airbnb 的 CamelCase 课程

After reading this article看完这篇文章

Update更新

I agree, in general, it is not a good idea to use regular expressions to parse HTML , so when a problem is relatively simple you can use the approach described above, but if you need something more comprehensive, please refer to @max answer .我同意,一般来说,使用正则表达式来解析 HTML 并不是一个好主意,所以当问题相对简单的时候你可以使用上面描述的方法,但是如果你需要更全面的东西,请参考@max answer

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM