0

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

しかし、それは実行されません。正規表現で検索する方法はありますか?

4

3 に答える 3

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[]>

スペースが特別に扱われているようです。

star を使用すると、この問題を回避できます。今、真の部分文字列マッチングを行っています。

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">}]>
于 2011-05-26T10:11:10.797 に答える
2

これは次のことを行う必要があります。

doc.search("span[@class^='foo'][@class$='bar']")
于 2009-12-30T11:34:54.183 に答える
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クラスを使用して要素を識別できます。これはエレガントでも一般的でもありませんが、より効率的であることが証明される可能性があります。

于 2009-12-29T09:05:16.597 に答える