Как вставить текст в текстовый файл по определенной строке или после определенного слова? - PullRequest
0 голосов
/ 25 октября 2019

Мне нужно создать метод, который будет вставлять переданные ему значения в тело файла index.html сразу после первого <body>.

У меня есть код:

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)

Как я могу убедиться, что числа, которые я передаю этому методу, вставлены в тело документа HTML? Также обратите внимание, что это только Ruby, а не Rails.

Ответы [ 3 ]

1 голос
/ 27 октября 2019

Анализ HTML с помощью регулярных выражений или любых других примитивных средств, таких как StringScanner, редко является хорошей идеей . Вместо этого используйте анализатор HTML ( nokogiri ), который на самом деле понимает HTML.

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"
1 голос
/ 25 октября 2019

Вы можете создать метод, подобный этому:

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

Он оставит исходный файл без изменений и создаст новый файл с нужными вам изменениями, потому что чтение и запись из одного и того же файла и в один и тот же файл одновременновремя не очень хорошая идея. Вызов метода следующим образом:

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

Скопирует все содержимое из исходного файла index.html в новый файл new_index.html, а также добавит 20, " " и 20 вновая строка после тега <body>. После этого, если вы довольны результатами, вы можете удалить / переместить старый файл и переименовать новый файл.

0 голосов
/ 26 октября 2019

В Ruby есть встроенный класс StringScanner, который можно использовать как удобный способ найти положение некоторого шаблона внутри строки.

Почему это можетбыть полезным в вашем случае? Вы можете попытаться найти индекс первого символа после тега <body>.

Зная этот индекс, вы можете легко вставить подстроку в нужное место в вашем HTML.

Вотпример:

<!-- 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)

Итак, вероятно, ваш класс будет выглядеть следующим образом:

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)

В качестве последнего примечания: если у вас нет особых требований,пожалуйста, используйте CamelCase для имен классов, как это предлагается большинством руководств по стилю Ruby. Вот несколько примеров: Rubocop , Airbnb .

Источники:

  1. StringScanner
  2. Строка # insert
  3. File.read
  4. File.write
  5. CamelCaseКлассы по Rubocop
  6. CamelCase Классы по Airbnb

После прочтения этой статьи

Обновление

Согласенв общем случае нецелесообразно использовать регулярные выражения для разбора HTML , поэтому, когда проблема относительно проста, вы можете использовать описанный выше подход, но если вам нужно что-то более всеобъемлющее, обратитесь к @ максимальный ответ .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...