用正则表达式搜索Hpricot

时间:2009-12-29 04:33:56

标签: ruby regex hpricot

我正在尝试使用Hpricot来获取带有我不知道的类名的范围内的值。我知道它遵循模式“foo_ [几位数] _bar”。

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

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

但这不会运行。有没有办法用正则表达式搜索?

3 个答案:

答案 0 :(得分:3)

这应该做:

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

除此之外,我们还可以提供一些其他类似表达式的更多示例:

对于以下文档:

我们得到每个查询的输出结果:

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">}]>

答案 1 :(得分:2)

这应该做:

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

答案 2 :(得分: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类识别元素。这远非优雅或一般,但可以证明更有效。