2011-08-14 13 views
6

tengo un fragmento de código que estoy tratando de analizar con nokogiri que tiene este aspecto:Nokogiri a Split contenido en las etiquetas BR

<td class="j"> 
    <a title="title text1" href="http://link1.com">Link 1</a> (info1), Blah 1,<br> 
    <a title="title text2" href="http://link2.com">Link 2</a> (info1), Blah 1,<br> 
    <a title="title text2" href="http://link3.com">Link 3</a> (info2), Blah 1 Foo 2,<br> 
</td> 

tengo acceso a la fuente de la td.j usando algo como esto : data_items = doc.css("td.j")

Mi objetivo es dividir cada una de esas líneas en una matriz de valores hash. El único punto de división lógico que puedo ver es dividir en los BR y luego usar algunos regex en la cadena.

Me preguntaba si hay una mejor manera de hacer esto tal vez solo con nokogiri? Incluso si pudiera usar nokogiri para absorber los 3 elementos de la línea, me facilitaría las cosas, ya que podría hacer algunos análisis regex en el resultado .content.

No estoy seguro de cómo usar Nokogiri para tomar las líneas que terminan en br, ¿debería usar xpaths? cualquier dirección es apreciada! gracias

Respuesta

1

Si sus datos realmente son tan regulares y no necesita los atributos de los elementos <a>, entonces podría analizar el texto de cada celda de tabla sin tener que preocuparse por los elementos <br>.

Dada algo de HTML como este en html:

<table> 
    <tbody> 
     <tr> 
      <td class="j"> 
       <a title="title text1" href="http://link1.com">Link 1</a> (info1), Blah 1,<br> 
       <a title="title text2" href="http://link2.com">Link 2</a> (info1), Blah 1,<br> 
       <a title="title text2" href="http://link3.com">Link 3</a> (info2), Blah 1 Foo 2,<br> 
      </td> 
      <td class="j"> 
       <a title="title text1" href="http://link4.com">Link 4</a> (info1), Blah 2,<br> 
       <a title="title text2" href="http://link5.com">Link 5</a> (info1), Blah 2,<br> 
       <a title="title text2" href="http://link6.com">Link 6</a> (info2), Blah 2 Foo 2,<br> 
      </td> 
     </tr> 
     <tr> 
      <td class="j"> 
       <a title="title text1" href="http://link7.com">Link 7</a> (info1), Blah 3,<br> 
       <a title="title text2" href="http://link8.com">Link 8</a> (info1), Blah 3,<br> 
       <a title="title text2" href="http://link9.com">Link 9</a> (info2), Blah 3 Foo 2,<br> 
      </td> 
      <td class="j"> 
       <a title="title text1" href="http://linkA.com">Link A</a> (info1), Blah 4,<br> 
       <a title="title text2" href="http://linkB.com">Link B</a> (info1), Blah 4,<br> 
       <a title="title text2" href="http://linkC.com">Link C</a> (info2), Blah 4 Foo 2,<br> 
      </td> 
     </tr> 
    </tbody> 
</table> 

Usted puede hacer esto:

chunks = doc.search('.j').map { |td| td.text.strip.scan(/[^,]+,[^,]+/) } 

y tienen la siguiente:

[ 
    [ "Link 1 (info1), Blah 1", "Link 2 (info1), Blah 1", "Link 3 (info2), Blah 1 Foo 2" ], 
    [ "Link 4 (info1), Blah 2", "Link 5 (info1), Blah 2", "Link 6 (info2), Blah 2 Foo 2" ], 
    [ "Link 7 (info1), Blah 3", "Link 8 (info1), Blah 3", "Link 9 (info2), Blah 3 Foo 2" ], 
    [ "Link A (info1), Blah 4", "Link B (info1), Blah 4", "Link C (info2), Blah 4 Foo 2" ] 
] 

en chunks. Entonces podrías convertir eso a la forma de hash que necesites.

17

No estoy seguro del punto de utilizar una matriz de valores hash, y sin un ejemplo no puedo sugerir algo. Sin embargo, para dividir el texto en las etiquetas <br>, me gustaría ir de esta manera:

require 'nokogiri' 

doc = Nokogiri::HTML('<td class="j"> 
    <a title="title text1" href="http://link1.com">Link 1</a> (info1), Blah 1,<br> 
    <a title="title text2" href="http://link2.com">Link 2</a> (info1), Blah 1,<br> 
    <a title="title text2" href="http://link3.com">Link 3</a> (info2), Blah 1 Foo 2,<br> 
</td>') 

doc.search('br').each do |n| 
    n.replace("\n") 
end 
doc.at('tr.j').text.split("\n") # => ["", " Link 1 (info1), Blah 1,", "Link 2 (info1), Blah 1,", "Link 3 (info2), Blah 1 Foo 2,"] 

Esto nos puede acercar más a un hash:

Hash[*doc.at('td.j').text.split("\n")[1 .. -1].map{ |t| t.strip.split(',')[0 .. 1] }.flatten] # => {"Link 1 (info1)"=>" Blah 1", "Link 2 (info1)"=>" Blah 1", "Link 3 (info2)"=>" Blah 1 Foo 2"} 
+0

Esto funcionó para mí. ¡Muchas gracias! –

Cuestiones relacionadas