Как правильно сделать замену между двумя индексами в строке в ruby? - PullRequest
0 голосов
/ 12 апреля 2011

Я использую nokogiri и ruby ​​для написания некоторых сценариев развертывания, и мне нужно обновить файл из многих источников информации.Первый файл, который я перебираю, я просто делаю простой заменой на gsub

File.open(@sql_file, 'w') { |file| file.puts text.gsub(/#{find}/, replace.to_s) }

Это прекрасно работает для первого файла, но во второй раз мне нужно разобрать текст, который я заменилизначально и потенциально обновить его.Используя Nokogiri, я придумал следующее:

def write_changes(find, replace)
  text = ''
  text = File.read(@sql_file)
  if text =~ /#{find}/
    File.open(@sql_file, 'w') do |file| 
      file.puts text.gsub(/#{find}/, replace.to_s)
    end
  else
    xml = Nokogiri::XML.parse(replace)
    element xml.at_xpath('//items')
  end
end

Может быть, не очень рубин: иш, но это работает.Однако проблема здесь заключается в том, что мне нужно разобрать

<items id="">
  <item />
</items>

из текста в файле, чтобы я мог использовать Nokogiri для обновления этого текста, а затем заменить его своими изменениями.

Так что, в общем, я думаю, мне нужно найти startindex моего тега items, в котором совпадает идентификатор, а затем вырезать все от <items id=""> до </items>.

Имеет ли это смысл?Должен ли я уточнить?

РЕДАКТИРОВАТЬ 1. У меня что-то работает, но я не могу понять последнюю часть.

    original = text[begin_index, end_index]
    xml2 = Nokogiri::XML.parse(original)
    update_element_values(xml, xml2)
    add_missing_elements(xml, xml2)
    # text[begin_index, end_index] = xml2.root.to_s
    text.insert(begin_index, xml2.root.to_s)
    File.open(@sql_file, 'w') { |file| file.puts text }

, если я раскомментирую строкуэто заменяет индексы, и я получаю некоторый поврежденный результат с отсутствием большей части.

Если я использую версию вставки, я получаю дубликаты для каждого файла, который пытаюсь объединить.Как правильно сделать замену между двумя индексами в строке в ruby?

1 Ответ

0 голосов
/ 18 апреля 2011

Мое решение, вдохновленное комментарием @ Эндрю, заключалось в том, чтобы использовать текст open как html-документ, чтобы иметь возможность перейти к xpath и выполнить его замену.После этого я просто очищаю сгенерированные заголовки HTML.Хотелось бы, чтобы был лучший способ.

def replace_provider(xml)
  element = xml.at_xpath('//provider')
  return if element.nil?

  doc = Nokogiri::HTML(open(@sql_file))
  original_xml = doc.at_xpath("//provider[@name=\"#{element['name']}\"]")
  return if original_xml.nil?

  update_element_values(xml, original_xml)
  add_missing_elements(xml, original_xml)

  doc.xpath("//provider[@name=\"#{element['name']}\"]") do |item|
    item.replace original_xml
  end
  text = remove_all_html_tags(doc)
  File.open(@sql_file, 'w') { |file| file.puts text }
end
...