Извлечь все URL внутри строки в Ruby - PullRequest
5 голосов
/ 19 февраля 2010

У меня есть текстовое содержимое со списком URL-адресов, содержащихся в нем.

Я пытаюсь собрать все URL-адреса и поместить их в массив.

У меня есть этот код

content = "Here is the list of URLs: http://www.google.com http://www.google.com/index.html"

urls = content.scan(/^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$/ix)

Я пытаюсь получить конечные результаты:

['http://www.google.com', 'http://www.google.com/index.html']

Вышеприведенный код работает неправильно. Кто-нибудь знает, что я делаю не так?

Спасибо

Ответы [ 4 ]

44 голосов
/ 09 мая 2011

Легко:

ruby-1.9.2-p136 :006 > require 'uri'
ruby-1.9.2-p136 :006 > URI.extract(content, ['http', 'https'])
  => ["http://www.google.com", "http://www.google.com/index.html"] 
5 голосов
/ 19 февраля 2010

Другой подход, отличающийся от мыслительной школы "идеал враг хорошего"

urls = content.split(/\s+/).find_all { |u| u =~ /^https?:/ }
5 голосов
/ 19 февраля 2010

Я не проверял синтаксис вашего регулярного выражения, но String.scan создаст массив, каждый из членов которого является массивом групп, соответствующих вашему регулярному выражению. Поэтому я ожидаю, что результат будет:

[['http', '.google.com'], ...]

Вам понадобятся несоответствующие группы /(?:stuff)/, если вы хотите формат, который вы указали.

Редактировать (глядя на регулярное выражение): Кроме того, ваше регулярное выражение выглядит немного неправильно. Вам не нужны начальные и конечные якоря (^ и $), так как вы не ожидаете совпадения в начале и конце content. Во-вторых, если ваш ([0-9]{1,5})? пытается захватить номер порта, я думаю, вам не хватает двоеточия для отделения домена от порта.

Дальнейшее редактирование после игры: Я думаю, вы хотите что-то вроде этого:

content = "Here is the list of URLs: http://www.google.com http://www.google.com/index.html http://example.com:3000/foo"
urls = content.scan(/(?:http|https):\/\/[a-z0-9]+(?:[\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(?:(?::[0-9]{1,5})?\/[^\s]*)?/ix)
# => ["http://www.google.com", "http://www.google.com/index.html", "http://example.com:3000/foo"]

... но учтите, что он не будет совпадать с URL-адресами с чистым IP-адресом (например, http://127.0.0.1) из-за [a-z]{2,5} для TLD.

4 голосов
/ 23 июля 2012

только для вашего интереса:

В Ruby есть модуль URI, для которого реализовано регулярное выражение:

require "uri"

uris_you_want_to_grap = ['ftp','http','https','ftp','mailto','see']

html_string.scan(URI.regexp(uris_you_want_to_grap)) do |*matches|
  urls << $&
end

Для получения дополнительной информации посетите Ruby Ref: URI

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