Разбор регулярных выражений с использованием Nokogiri

Используя 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?


person There Are Four Lights    schedule 17.07.2010    source источник


Ответы (2)


Чтобы получить лучший ответ, вам нужно будет точно указать, какой формат имеют значения 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, в частности захватывает метод для получения более подробной информации.

person mikej    schedule 17.07.2010
comment
Примечание: если нет совпадения, это не значит, что ваши переменные, например. dollars будет nil, в этом проблема - это приведет к попытке вызвать метод captures для nil, которая завершится ошибкой, поэтому вам может понадобиться проверка. - person mikej; 17.07.2010
comment
Ах. Хорошо я понял. Так что же такое метод захвата? Потому что теперь он отлично работает без захватов для меня. - person There Are Four Lights; 17.07.2010
comment
Я добавил еще несколько пояснений к ответу. Надеюсь, это поможет. - person mikej; 17.07.2010

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

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}
person the Tin Man    schedule 20.12.2011
comment
есть ли способ для nokogiri просто вернуть данные, если они соответствуют определенному шаблону регулярного выражения, вместо того, чтобы возвращать все, а затем применять к нему логику? esp, при синтаксическом анализе большого XML-файла, может быть, если nokogiri будет возвращать только те биты, которые нам нужны, будет быстрее? Или фильтрация позже будет быстрее? благодаря. - person B A; 30.06.2016
comment
XPath2 поддерживает регулярное выражение, а старый XPath1 — нет. Nokogiri CSS предоставляет несколько расширений типа jQuery, которые не допускают регулярных выражений, но могут помочь. Быстрее позволить библиотеке libXML2 выполнить подъем/поиск, чем возвращать каждый узел в Nokogiri, а затем просеивать их, но вы можете убедиться в этом сами, используя тесты. - person the Tin Man; 30.06.2016