2009-12-29 74 views
0

我想用Hpricot来获取类内名称的值,我不知道。我知道它遵循模式“foo_ [几个数字] _bar”。用正则表达式搜索Hpricot

现在,我将整个包含元素作为字符串并使用正则表达式来解析标记的字符串。该解决方案有效,但它看起来真的很丑。

doc = Hpricot(open("http://scrape.example.com/search?q=#{ticker_symbol}")) 
elements = doc.search("//span[@class='pr']").inner_html 
string = "" 
elements.each do |attr| 
    if(attr =~ /foo_\d+_bar/) 
    string = attr 
    end 
end 
# get rid of the span tags, just get the value 
string.sub!(/<\/span>/, "") 
string.sub!(/<span.+>/, "") 

return string 

看来应该有更好的方法来做到这一点。我想要做类似的事情:

elements = doc.search("//span[@class='" + /foo_\d+_bar/ + "']").inner_html 

但是,这并不运行。有没有一种使用正则表达式进行搜索的方法?

回答

2

这应该这样做:

doc.search("span[@class^='foo'][@class$='bar']") 
+0

这看起来像我想要的。我会试一试看看结果如何。 – AaronM 2010-01-02 22:11:01

+0

工作完美!这正是我想要的。 – AaronM 2010-01-03 23:31:56

0

可以在解析之前修改传入的html。

html = open("http://scrape.example.com/search?q=#{ticker_symbol}").string 
html.gsub!(/class="(foo_\d+_bar)"/){ |s| "class=\"foo_bar #{$1}\"" } 
doc = Hpricot(html) 

之后,您可以使用foo_bar类标识元素。这远非优雅或一般,但可以证明更有效。

+0

感谢您的建议。这将工作,除了它返回一个字符串。我宁愿拿回一个hpricot Element对象。 – AaronM 2010-01-03 23:33:27

3

这应该这样做:

doc.search("span[@class^='foo'][@class$='bar']") 

除了这一点,我们可以给一些其他类似的表述是如何工作的一些例子:

对于文档如下:

我们得到了outp ut以下为每个查询:

doc.search("//meta[@content='abcxy def ghi jklmn']") 
=> #<Hpricot::Elements[{emptyelem <meta content="abcxy def ghi jklmn">}]> 

这是我们所期望的。

doc.search("//meta[@content='def']") 
=> #<Hpricot::Elements[]> 

正如您所看到的=正在寻找完全匹配。

doc.search("//meta[@content~='def']") 
=> #<Hpricot::Elements[{emptyelem <meta content="abcxy def ghi jklmn">}]> 

用〜我们可以做一个子串匹配;但并非真正符合你的期望。

例如,请参阅以下内容。

doc.search("//meta[@content~=' def ']") 
=> #<Hpricot::Elements[]> 

似乎空间被特别对待。

随着明星我们可以绕过这个问题。现在我们正在做真正的子字符串匹配。

doc.search("//meta[@content*=' def ']") 
=> #<Hpricot::Elements[{emptyelem <meta content="abcxy def ghi jklmn">}]> 

我们也可以做字符串开头和字符串结束匹配如下:

doc.search("//meta[@content^='def']") 
=> #<Hpricot::Elements[]> 

doc.search("//meta[@content^='ab']") 
=> #<Hpricot::Elements[{emptyelem <meta content="abcxy def ghi jklmn">}]> 

doc.search("//meta[@content$='mn']") 
=> #<Hpricot::Elements[{emptyelem <meta content="abcxy def ghi jklmn">}]> 

注意,这些空格字符都不是问题。

doc.search("//meta[@content$=' jklmn']") 
=> #<Hpricot::Elements[{emptyelem <meta content="abcxy def ghi jklmn">}]>