Анализ регулярных выражений с использованием Nokogiri - PullRequest
4 голосов
/ 17 июля 2010

Используя Nokogiri, мне нужно проанализировать указанный блок:

<div class="some_class">
  12 AB / 4+ CD
  <br/>
  2,600 Dollars
  <br/> 
</div>

Мне нужно получить значения ab, cd и dollars, если они существуют.

ab = p.css(".some_class").text[....some regex....]
cd = p.css(".some_class").text[....some regex....]
dollars = p.css(".some_class").text[....some regex....]

Это правильно?Если да, может ли кто-нибудь помочь мне с регулярным выражением для анализа значений ab, cd и dollars?

Ответы [ 2 ]

6 голосов
/ 17 июля 2010

Чтобы получить лучший ответ, вам необходимо уточнить, какой именно формат принимают значения AB, CD и Dollar, но вот решение, основанное на приведенном примере.Он использует группировку регулярных выражений () для сбора интересующей нас информации. (См. Нижнюю часть ответа для получения более подробной информации)

text = p.css(".some_class").text

# one or more digits followed by a space followed by AB, capture the digits
ab = text.match(/(\d+) AB/).captures[0] # => "12"

# one of more non digits followed by a literal + followed by CD
cd = text.match(/(\d+\+) CD/).captures[0] # => "4+"

# digits or commas followed by "Dollars"
dollars = text.match(/([\d,]+) Dollars/).captures[0] # => "2,600"

Обратите внимание, что если совпадения нет, то String#match возвращаетnil, поэтому, если значения могут не существовать, вам понадобится проверка, например,

if match = text.match(/([\d,]+) Dollars/)
  dollars = match.captures[0]
end

Дополнительное объяснение захватов

Чтобы соответствовать количеству AB, нам нуженшаблон /\d+ AB/ для идентификации правой части текста.Однако нас действительно интересует только числовая часть, поэтому мы заключаем ее в скобки, чтобы ее можно было извлечь.Например,

irb(main):027:0> match = text.match(/(\d+) AB/)
=> #<MatchData:0x2ca3440>           # the match method returns MatchData if there is a match, nil if not
irb(main):028:0> match.to_s         # match.to_s gives us the entire text that matched the pattern
=> "12 AB"
irb(main):029:0> match.captures     
=> ["12"]
# match.captures gives us an array of the parts of the pattern that were enclosed in ()
# in our example there is just 1 but there could be multiple
irb(main):030:0> match.captures[0]
=> "12"                             # the first capture - the bit we want

Более подробную информацию смотрите в документации по MatchData , в частности, по методу captures .

0 голосов
/ 20 декабря 2011

Это старая ветка, но я наткнулся на нее.Вот как я могу найти значения и способ хранения значений:

require "ap"
require "nokogiri"

xml = <<EOT
<div class="some_class">
  12 AB / 4+ CD
  <br/>
  2,600 Dollars
  <br/> 
</div>
EOT

doc = Nokogiri::XML(xml)

some_class = doc.at('.some_class').text

values = some_class
  .scan(/([\d+]+) ([a-z,]+)/i)
  .each_with_object({}){ |(v,c), h| h[c] = v.to_i }

values # => {"AB"=>12, "CD"=>4, "Dollars"=>600}
...