RegEx Не работает в Ruby! - PullRequest
       1

RegEx Не работает в Ruby!

0 голосов
/ 24 июля 2010

Я использую следующее регулярное выражение

html.scan(Regexp.new(/Name:<\/td>(.*?)<\/td>/s))

для соответствия имени [Burkhart, Peterson &amp; Company] в этом

<td class="generalinfo_left" align="right">Name:</td>
<td class="generalinfo_right">Burkhart, Peterson &amp; Company</td>

Ответы [ 5 ]

4 голосов
/ 24 июля 2010

Обычно синтаксический анализ (X) HTML с использованием регулярных выражений является плохой практикой. В Ruby есть фантастическая Nokogiri библиотека, которая использует libxml2 для эффективного анализа XHTML.

Как говорится, ваш . не соответствует переводу строки. Используйте модификатор m для вашего регулярного выражения, который сообщает ., что нужно сопоставлять новые строки. Или константа Regexp :: MULTILINE. Документировано здесь

Ваше регулярное выражение также захватывает HTML перед требуемым текстом.

Использование nokogiri и XPath означало бы, что вы можете получить содержимое этой ячейки таблицы, ссылаясь на ее класс CSS. Как это:

#!/usr/bin/env ruby

require 'nokogiri'

doc = Nokogiri::HTML DATA.read

p doc.at("td[@class='generalinfo_right']").text

__END__
<td class="generalinfo_left" align="right">Name:</td>
<td class="generalinfo_right">Burkhart, Peterson &amp; Company</td>

Который вернется "Burkhart, Peterson & Company"

2 голосов
/ 24 июля 2010

/m делает точку новой строки

0 голосов
/ 24 июля 2010

Вы можете проверить, что все ответы, предлагающие добавить / m или Regexp :: MULTILINE, верны, перейдя на rubular.com.

Я также проверил решение в консоли, а также изменил регулярное выражение, чтобыон будет возвращать только имя вместо всего лишнего мусора.

    Loading development environment (Rails 2.3.8)
ree-1.8.7-2010.02 > html = '<td class="generalinfo_left" align="right">Name:</td>
ree-1.8.7-2010.02'> <td class="generalinfo_right">Burkhart, Peterson &amp; Company</td>
ree-1.8.7-2010.02'> '
 => "<td class="generalinfo_left" align="right">Name:</td>\n<td class="generalinfo_right">Burkhart, Peterson &amp; Company</td>\n" 
ree-1.8.7-2010.02 > html.scan(Regexp.new(/Name:<\/td>(.*?)<\/td>/m))
 => [["\n<td class="generalinfo_right">Burkhart, Peterson &amp; Company"]] 
ree-1.8.7-2010.02 > html.scan(Regexp.new(/Name:<\/td>.*<td[^>]*>(.*?)<\/td>/m))
 => [["Burkhart, Peterson &amp; Company"]] 
ree-1.8.7-2010.02 > 
0 голосов
/ 24 июля 2010

html.scan(Regexp.new(/Name:<\/td>(.*?)<\/td>/s)) не соответствует символам новой строки; даже если он будет соответствовать этим символам, часть (.*?) будет захватывать все после </td>, включая <td class="generalinfo_right">.

Чтобы сделать регулярное выражение более универсальным и дать возможность соответствовать точному тексту, который вы хотите, вы должны изменить код на

html.scan(Regexp.new(/Name:<\/td><td[^>]*>(.*?)<\/td>/s))

Регулярное выражение может быть лучше написано, однако.

Я бы также не советовал анализировать содержимое HTML / XHTML с помощью регулярного выражения.

0 голосов
/ 24 июля 2010

Вы хотите использовать / м для многострочного режима:

str.scan(/Name:</td>(.*?)</td>/m)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...