Изменение текста внутри html-узлов - nokogiri - PullRequest
7 голосов
/ 29 августа 2011

Допустим, у меня есть следующий HTML:

<ul><li>Bullet 1.</li>
<li>Bullet 2.</li>
<li>Bullet 3.</li>
<li>Bullet 4.</li>
<li>Bullet 5.</li></ul>

Что я хочу с ним сделать, это заменить любые точки, вопросительные знаки или восклицательные знаки на себя и конечную звездочку, которая находится внутри узла HTML, а затем преобразовать обратно в HTML. Таким образом, результат будет:

<ul><li>Bullet 1.*</li>
<li>Bullet 2.*</li>
<li>Bullet 3.*</li>
<li>Bullet 4.*</li>
<li>Bullet 5.*</li></ul>

Я немного возился с этим в IRB, но не могу понять. вот код, который у меня есть:

 html = "<ul><li>Bullet 1.</li>
<li>Bullet 2.</li>
<li>Bullet 3.</li>
<li>Bullet 4.</li>
<li>Bullet 5.</li></ul>"

doc = Nokogiri::HTML::DocumentFragment.parse(html)
doc.search("*").map { |n| n.inner_text.gsub(/(?<=[.!?])(?!\*)/, "#{$1}*") }

Возвращаемый массив анализируется правильно, но я просто не уверен, как преобразовать его обратно в HTML. Есть ли другой метод, который я могу использовать, чтобы изменить inner_text как таковой?

Ответы [ 2 ]

8 голосов
/ 29 августа 2011

А как насчет этого кода?

doc.traverse do |x|
  if x.text?
    x.content = x.content.gsub(/(?<=[.!?])(?!\*)/, "#{$1}*")
  end
end

Метод traverse делает то же самое, что и search("*").each. Затем вы проверяете, что узел является Nokogiri::XML::Text, и, если это так, измените content, как вы пожелаете.

1 голос
/ 29 августа 2011

Благодаря посту здесь Nokogiri заменил значения тега , я смог немного его изменить и разобраться.

doc = Nokogiri::HTML::DocumentFragment.parse(html)
doc.search("*").each do |node|
  dummy = node.add_previous_sibling(Nokogiri::XML::Node.new("dummy", doc))
  dummy.add_previous_sibling(Nokogiri::XML::Text.new(node.to_s.gsub(/(?<=[.!?])(?!\*)/, "#{$1}*"), doc))
  node.remove
  dummy.remove
end

puts doc.to_html.gsub("&lt;", "<").gsub("&gt;", ">")
...