2010-02-19 31 views
5

Tôi có một số nội dung văn bản với danh sách các URL chứa trong đó.Trích xuất tất cả các url bên trong một chuỗi trong Ruby

Tôi đang cố gắng lấy tất cả các URL ra và đặt chúng vào một mảng.

tôi có mã này

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) 

Tôi cố gắng để có được kết quả cuối cùng là:

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

Đoạn mã trên dường như không được làm việc một cách chính xác. Có ai biết tôi đang làm gì sai không?

Cảm ơn

Trả lời

5

Một cách tiếp cận khác nhau, từ hoàn hảo là-the-kẻ thù-of-the-tốt trường phái tư tưởng:

urls = content.split(/\s+/).find_all { |u| u =~ /^https?:/ } 
+1

Tôi sẽ cung cấp cho bạn sự đơn giản. Điều này cũng có thể là tất cả những gì cần thiết. – Chowlett

+1

Tôi tốt nghiệp trường đó! –

+0

Cách tiếp cận này sẽ bỏ lỡ nhiều URL hợp lệ và chọn sai nhiều URL không hợp lệ. – sferik

5

tôi đã không kiểm tra cú pháp của regex của bạn, nhưng String.scan sẽ tạo ra một mảng, mỗi người trong số các thành viên là một mảng của các nhóm phù hợp của regex của bạn. Vì vậy, tôi mong đợi kết quả là:

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

Bạn sẽ cần nhóm /(?:stuff)/ không phù hợp nếu bạn muốn định dạng mà bạn đã đưa ra.

Chỉnh sửa (xem regex): Ngoài ra, regex của bạn có vẻ hơi sai. Bạn không muốn neo bắt đầu và kết thúc (^$), vì bạn không mong đợi các kết quả phù hợp ở đầu và cuối của content. Thứ hai, nếu ([0-9]{1,5})? của bạn đang cố gắng nắm bắt số cổng, tôi nghĩ bạn đang thiếu dấu hai chấm để tách miền khỏi cổng.

Tiếp tục chỉnh sửa, sau khi chơi: Tôi nghĩ rằng bạn muốn một cái gì đó như thế này:

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"] 

... nhưng lưu ý rằng nó sẽ không phù hợp với URL địa chỉ IP thuần túy (như http://127.0.0.1), vì số [a-z]{2,5} cho TLD.

42

dễ dàng:

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"] 
+0

tại sao điều này không được đánh dấu là câu trả lời đúng. grml –

+0

Điều này phải được đánh dấu là câu trả lời. Xa thanh lịch hơn. – adeluccar

4

chỉ quan tâm đến:

Ruby có Mô-đun URI, có một regex được triển khai để thực hiện những việc như vậy:

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 

Để biết thêm thông tin, hãy truy cập Ruby Ref: URI

Các vấn đề liên quan