Как мне сопоставить строку с элементом массива? - PullRequest
0 голосов
/ 21 февраля 2012

У меня есть следующее:

titles = []
url = []

titles.each do |link|
  if link[:href] =~ 'http://www.google.com'
    url.push(link[:href])
  end
end

Но я продолжаю получать ошибку TypeError:

TypeError: type mismatch: String given

PS Я пытаюсь использовать Nokogiri для анализа ссылок, возвращаемых с определенного URL.Если у кого-то есть ссылки, кроме учебника / вики по Nokogiri, о том, как лучше всего это сделать, пожалуйста, дайте мне знать.

Ответы [ 4 ]

2 голосов
/ 21 февраля 2012

Я пытаюсь использовать Nokogiri для анализа ссылок, возвращаемых с определенного URL.

Хотя Нокогири облегчает, есть еще более простые способы. Встроенный в Ruby URI имеет метод URI.extract . Из документов:

Извлекает URI из строки. Если указан блок, выполняется итерация по всем совпадающим URI. Возвращает nil, если данный блок или массив с совпадениями. Использование

require "uri"

URI.extract("text here http://foo.example.org/bla and here mailto:test@example.com and here also.")
# => ["http://foo.example.com/bla", "mailto:test@example.com"]

Вы можете указать, какие схемы использовать, поэтому он будет получать только HTTP или HTTPS или все, что вы ищете.

1 голос
/ 22 февраля 2012

Видя из последующих комментариев, что вы действительно хотите искать текстовую часть всех ссылок, это определенно то, что можно сделать с помощью Nokogiri. Фактически это можно сделать с помощью одного выражения XPath!

urls = doc.xpath("//a[contains(text(), '#{search_term}')]/@href")

где search_term содержит искомую строку.

Это можно изменить, чтобы сделать его нечувствительным к регистру. К сожалению, Nokogiri использует XPath 1.0, поэтому удобная функция XPath 2.0 lower-case() недоступна. Существует обходной путь: использование translate().

upper = ("A".."Z").to_a.join
lower = ("a".."z").to_a.join
urls = doc.xpath("//a[contains(translate(.,'#{upper}','#{lower}'), '#{search_term.downcase}')]/@href")
1 голос
/ 21 февраля 2012

Оператор =~ используется для сопоставления регулярных выражений, а не строк.

Match - если obj является регулярным выражением, используйте его как образец для сравнения с str, и возвращает позицию, с которой начинается совпадение, или ноль, если совпадения нет. В противном случае вызывает obj. = ~, Передавая str в качестве аргумента. По умолчанию = ~ в объекте возвращает ноль.

http://ruby -doc.org / ядро-1.9.3 / String.html # метод-я-3D-7E

Это будет работать, если вы хотите проверить, включен ли http://www.google.com в строку:

titles = []
url = []

titles.each do |link|
    if link[:href] =~ /http:\/\/www.google.com/
       url.push(link[:href])
    end
end
0 голосов
/ 21 февраля 2012

=~ используется для поиска совпадения регулярного выражения со строкой.Если есть совпадение, оно возвращает индекс совпадения , в противном случае возвращает nil объект.

В вашем следующем утверждении обе строки, отсюда и ошибка.

link[:href] =~ 'http://www.google.com'

Это должно быть что-то вроде этого

link[:href] =~ /http:\/\/www.google.com/
...