2010-09-08 26 views
15

Jak wyodrębnić wszystkie adresy URL z pliku tekstowego w Ruby?Jak wyodrębnić adresy URL z tekstu

Próbowałem niektórych bibliotek, ale w niektórych przypadkach nie. Jaki jest najlepszy sposób?

+4

Które biblioteki próbowaliście iw jaki sposób zawiedli? – Zaz

+0

Kiedy zadajemy takie pytanie, spodziewamy się, że spróbujesz rozwiązać problem. Chętnie pomożemy naprawić Twój kod, ale prośba o napisanie kodu jest nie na temat. Przeczytaj "[ask]" i "[mcve]". –

Odpowiedz

4

Jakie przypadki się nie udają?

Według biblioteki regexpert, można użyć

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

a następnie wykonać scan na tekście.

EDYCJA: Wydaje się, że wyrażenie regularne obsługuje pusty ciąg znaków. Wystarczy usunąć początkową (^$) i gotowe

+1

Interesujące, jak to wyrażenie regularne nie działa, gdy adres URL jest adresem IP – NullUserException

+1

Tak. W rzeczywistości głosowałem za twoją odpowiedzią z powodu "i dostosuj ją do twoich potrzeb". Nie udaje się również, gdy jest to użytkownik @ hasło lub używa się innego niż https? Lub jakiejkolwiek innej dziwnej sytuacji. Prawdopodobnie nie chcesz przeczytać http://tools.ietf.org/html/rfc3986, aby zacząć -_- – Chubas

+0

To się nie powiedzie jak powyżej. Pytam, po prostu, dlaczego nie jestem w stanie "i dostosować go do twoich potrzeb". – tapioco123

7

Można użyć wyrażenia regularnego i .scan()

string.scan(/(https?:\/\/([-\w\.]+)+(:\d+)?(\/([\w\/_\.]*(\?\S+)?)?)?)/) 

Można zacząć z tym regex i dostosować je w zależności od potrzeb.

82

Jeśli podoba Ci się za pomocą tego, co jest już dostępne dla Ciebie w Ruby:

require "uri" 
URI.extract("text here http://foo.example.org/bla and here mailto:[email protected] and here also.") 
# => ["http://foo.example.org/bla", "mailto:[email protected]"] 

Więcej: http://railsapi.com/doc/ruby-v1.8/classes/URI.html#M004495

+4

Błąd kończy się tekstem z ":" http: //blog.apptamers.com/post/48613650042/uri-extract-incorrect-in-ruby-1-9-3 –

+9

'URI.extract (yourString,/http (s)? | mailto /)' – titibouboul

+4

Czy istnieje mimo to wyodrębnianie adresów URL bez schematu? jak www.example.com –

10

Użyłem twitter-text gem

require "twitter-text" 
class UrlParser 
    include Twitter::Extractor 
end 

urls = UrlParser.new.extract_urls("http://stackoverflow.com") 
puts urls.inspect 
0
require 'uri'  
foo = #<URI::HTTP:0x007f91c76ebad0 URL:http://foobar/00u0u_gKHnmtWe0Jk_600x450.jpg> 
foo.to_s 
=> "http://foobar/00u0u_gKHnmtWe0Jk_600x450.jpg" 

edycja: wyjaśnienie

Dla tych, którzy mają problemy z analizowaniem URI za pomocą odpowiedzi JSON lub za pomocą narzędzia skrobiącego, takiego jak Nokogiri lub Mechanize, to rozwiązanie zadziałało u mnie.

+0

Być może powinieneś wyjaśnić swoją odpowiedź? Jeśli to rzeczywiście jest odpowiedź? – Jensd

+0

Dodano dodatkowe wyjaśnienie. – Keon

+0

To nie ma sensu i nie jest poprawne pod względem składniowym. –

0

Jeśli wejście wygląda podobnie do tego:

"http://i.imgur.com/c31IkbM.gifv;http://i.imgur.com/c31IkbM.gifvhttp://i.imgur.com/c31IkbM.gifv" 

czyli adresy URL nie muszą mieć białą przestrzeń wokół nich, mogą być rozdzielane dowolnym separatorem, lub nie mają ogranicznika między nimi w ogóle, można użyć następujące podejście:

def process_images(raw_input) 
    return [] if raw_input.nil? 
    urls = raw_input.split('http') 
    urls.shift 
    urls.map { |url| "http#{url}".strip.split(/[\s\,\;]/)[0] } 
end 

Mam nadzieję, że pomoże!