2009-10-12 9 views
23

Étant donné:Comment faire une recherche regex dans Nokogiri pour un texte qui correspond à un certain début?

require 'rubygems' 
require 'nokogiri' 
value = Nokogiri::HTML.parse(<<-HTML_END) 
"<html> 
<body> 
    <p id='para-1'>A</p> 
    <div class='block' id='X1'> 
    <h1>Foo</h1> 
    <p id='para-2'>B</p> 
    </div> 
    <p id='para-3'>C</p> 
    <h2>Bar</h2> 
    <p id='para-4'>D</p> 
    <p id='para-5'>E</p> 
    <div class='block' id='X2'> 
    <p id='para-6'>F</p> 
    </div> 
</body> 
</html>" 
HTML_END 

Je veux faire quelque chose comme ce que je peux faire dans hpricot:

divs = value.search('//div[@id^="para-"]') 
  1. Comment puis-je faire une recherche de modèle pour les éléments dans le style XPath?
  2. Où puis-je trouver la documentation pour m'aider? Je n'ai pas vu ça dans les rdocs.
+0

PSA: Pour ceux qui tentent regex plus complexe, il est probable que ce que vous cherchez: http://stackoverflow.com/questions/649963/ nokogiri-recherche-pour-div-using-xpath – DreadPirateShawn

Répondre

64

Utilisez la fonction XPath starts-with:

value.xpath('//p[starts-with(@id, "para-")]').each { |x| puts x['id'] } 
+29

Wow, Aaron lui-même vient de répondre! – khelll

+1

@khelll Qu'y a-t-il de si cool à Aaron? –

+5

Auteur de Nokogiri et membre de l'équipe RoR. – khelll

16
divs = value.css('div[id^="para-"]') 
+0

c'est un épargnant de vie – Onichan

1
Nokogiri::XML::Node.send(:define_method, 'xpath_regex') { |*args| 
    xpath = args[0] 
    rgxp = /\/([a-z]+)\[@([a-z\-]+)~=\/(.*?)\/\]/ 
    xpath.gsub!(rgxp) { |s| m = s.match(rgxp); "/#{m[1]}[regex(.,'#{m[2]}','#{m[3]}')]" } 
    self.xpath(xpath, Class.new { 
    def regex node_set, attr, regex 
     node_set.find_all { |node| node[attr] =~ /#{regex}/ } 
    end 
    }.new) 
} 

Utilisation:

divs = Nokogiri::HTML(page.root.to_html). 
    xpath_regex("//div[@class~=/axtarget$/]//div[@class~=/^carbo/]")