2009-11-26 45 views
65

Làm cách nào để kiểm tra xem chuỗi có phải là URL hợp lệ không?Cách kiểm tra xem URL có hợp lệ không

Ví dụ:

http://hello.it => yes 
http:||bra.ziz, => no 

Nếu đây là URL hợp lệ làm thế nào tôi có thể kiểm tra nếu điều này là liên quan đến một tập tin hình ảnh?

+0

url bạn cung cấp có vẻ là url tuyệt đối, ý của bạn là gì so với tệp hình ảnh – johannes

+0

Tôi đã đăng [UriValidator với thông số kỹ thuật] (http://stackoverflow.com/a/19423623/356895). – JJD

Trả lời

146

Sử dụng các mô-đun URI phân phối với Ruby:

require 'uri' 

if url =~ URI::regexp 
    # Correct URL 
end 

Giống như Alexander Günther nói trong các ý kiến, nó sẽ kiểm tra xem một chuỗi chứa một URL.

Để kiểm tra xem chuỗi URL, sử dụng:

url =~ /\A#{URI::regexp}\z/ 

Nếu bạn chỉ muốn kiểm tra URL web (http hoặc https), sử dụng này:

url =~ /\A#{URI::regexp(['http', 'https'])}\z/ 
+21

Điều đó dường như không hoạt động: ''http: //: 5984/asdf' = ~ URI :: regexp' và' 'http :: 5984/asdf' = ~ URI :: regexp' cả trả về 0. Tôi mong đợi họ trả về nil vì không ai trong số họ là các URI hợp lệ. – awendt

+3

Không phải: 5984 cổng 5984 trên máy chủ cục bộ? – mxcl

+2

Nó thực sự kiểm tra nếu một biến có chứa một url hợp lệ. Nó sẽ chấp nhận "http: // example com" dưới dạng URL hợp lệ. Bởi vì nó chứa một. Nhưng nó không phải là hữu ích nếu bạn mong đợi toàn bộ điều là URL. –

-2

Bạn cũng có thể sử dụng một regex, có lẽ một cái gì đó như http://www.geekzilla.co.uk/View2D3B0109-C1B2-4B4E-BFFD-E8088CBC85FD.htm giả định regex này là chính xác (tôi đã không hoàn toàn kiểm tra nó) sau đây sẽ hiển thị giá trị của url.

url_regex = Regexp.new("((https?|ftp|file):((//)|(\\\\))+[\w\d:\#@%/;$()~_?\+-=\\\\.&]*)") 

urls = [ 
    "http://hello.it", 
    "http:||bra.ziz" 
] 

urls.each { |url| 
    if url =~ url_regex then 
     puts "%s is valid" % url 
    else 
     puts "%s not valid" % url 
    end 
} 

Ví dụ đầu ra ở trên:

http://hello.it is valid 
http:||bra.ziz not valid 
+4

Còn sơ đồ mailto thì sao? Hoặc telnet, gopher, nntp, rsync, ssh, hoặc bất kỳ chương trình nào khác? URL phức tạp hơn một chút so với HTTP và FTP. –

+0

Viết regex để xác thực URL là khó khăn. Quan tâm làm gì? – Rimian

+0

@Rimian, bạn phải bận tâm bởi vì tất cả các 'URI' có thể làm là trong thực tế bị hỏng. Xem các bình luận theo rất nhiều câu trả lời được nêu ở trên. Không chắc chắn nếu câu trả lời của Janie là đúng nhưng upvoting để hy vọng mọi người xem xét nó nghiêm túc hơn. TBH Tôi sẽ làm 'url.start_with? (" Http: // ") || url.start_with? ("https: //") 'bởi vì tôi chỉ cần HTTP và người dùng phải chịu trách nhiệm sử dụng các URL thích hợp. – akostadinov

34

Tương tự như các câu trả lời ở trên, tôi tìm thấy sử dụng regex này là hơi chính xác hơn:

URI::DEFAULT_PARSER.regexp[:ABS_URI] 

Điều đó sẽ làm mất hiệu lực URL với không gian, trái ngược với URI.regexp cho phép không gian vì lý do nào đó.

Gần đây tôi đã tìm thấy một lối tắt được cung cấp cho các rgexps URI khác nhau. Bạn có thể truy cập bất kỳ số nào trong số URI::DEFAULT_PARSER.regexp.keys trực tiếp từ URI::#{key}.

Ví dụ: :ABS_URI regexp có thể được truy cập từ URI::ABS_URI.

+1

Nếu bạn định sử dụng URI.parse tại bất kỳ thời điểm nào, đây chắc chắn là cách để đi. URI :: regexp khớp với một số URL nhất định sẽ thất bại khi sử dụng URI.parse sau. Cảm ơn vì tiền hỗ trợ. – markquezada

+0

Đáng buồn thay, điều này chỉ có sẵn trên Ruby 1.9, không phải 1.8. –

+1

Nhưng, nó hoạt động: '/^# {URI.regexp} $ /'. Vấn đề là 'URI.regexp' không neo. Một chuỗi có khoảng trắng không xác thực không gian là một phần của URI, nhưng mọi thứ dẫn đến không gian. Nếu đoạn đó trông giống như một URI hợp lệ, thì trận đấu thành công. –

19

Tôi thích số Addressable gem. Tôi đã thấy rằng nó xử lý các URL thông minh hơn.

require 'addressable/uri' 

SCHEMES = %w(http https) 

def valid_url?(url) 
    parsed = Addressable::URI.parse(url) or return false 
    SCHEMES.include?(parsed.scheme) 
rescue Addressable::URI::InvalidURIError 
    false 
end 
+2

Tôi chỉ cần cung cấp địa chỉ :: URI.parse() với các chuỗi lạ nhất để xem những gì nó từ chối. Nó chấp nhận những thứ điên rồ. Tuy nhiên chuỗi đầu tiên nó không chấp nhận là ":-)". Hmm. – mvw

10

Đây là một entry khá cũ, nhưng tôi nghĩ rằng tôi muốn đi trước và đóng góp:

String.class_eval do 
    def is_valid_url? 
     uri = URI.parse self 
     uri.kind_of? URI::HTTP 
    rescue URI::InvalidURIError 
     false 
    end 
end 

Bây giờ bạn có thể làm một cái gì đó như:

if "http://www.omg.wtf".is_valid_url? 
    p "huzzah!" 
end 
+2

Công trình này * nhiều * tốt hơn so với các giải pháp trên. Nó không có các thông báo được liệt kê ở trên, và cũng không chấp nhận uris như javascript: alert ('spam'). – bchurchill

+2

nhưng nó cũng khớp với 'http: /', có thể không phải là thứ bạn muốn. –

+0

Đủ công bằng @ bjeanes. Cảm ơn bạn đã chỉ ra điều đó! –

2

Đây là một chút bit cũ nhưng đây là cách tôi làm điều đó. Sử dụng mô-đun URI của Ruby để phân tích cú pháp URL. Nếu nó có thể được phân tích cú pháp thì đó là một URL hợp lệ. (Nhưng điều đó không có nghĩa là có thể truy cập được.)

URI hỗ trợ nhiều chương trình, ngoài ra bạn có thể thêm các chương trình tùy chỉnh bản thân:

irb> uri = URI.parse "http://hello.it" rescue nil 
=> #<URI::HTTP:0x10755c50 URL:http://hello.it> 

irb> uri.instance_values 
=> {"fragment"=>nil, 
"registry"=>nil, 
"scheme"=>"http", 
"query"=>nil, 
"port"=>80, 
"path"=>"", 
"host"=>"hello.it", 
"password"=>nil, 
"user"=>nil, 
"opaque"=>nil} 

irb> uri = URI.parse "http:||bra.ziz" rescue nil 
=> nil 


irb> uri = URI.parse "ssh://hello.it:5888" rescue nil 
=> #<URI::Generic:0x105fe938 URL:ssh://hello.it:5888> 
[26] pry(main)> uri.instance_values 
=> {"fragment"=>nil, 
"registry"=>nil, 
"scheme"=>"ssh", 
"query"=>nil, 
"port"=>5888, 
"path"=>"", 
"host"=>"hello.it", 
"password"=>nil, 
"user"=>nil, 
"opaque"=>nil} 

Xem the documentation để biết thêm thông tin về các mô-đun URI.

25

Sự cố với câu trả lời hiện tại là a URI is not an URL.

URI có thể được phân loại thêm làm định vị, tên hoặc cả hai. Cụm từ "Uniform Resource Locator" (URL) đề cập đến tập con của URI , ngoài việc xác định tài nguyên, cung cấp phương tiện tìm nguồn tài nguyên bằng cách mô tả cơ chế truy cập chính (ví dụ: "vị trí" mạng của nó).

Vì URL là tập hợp con của URI, rõ ràng là việc đối sánh riêng cho URI sẽ khớp thành công các giá trị không mong muốn. Ví dụ, URNs:

"urn:isbn:0451450523" =~ URI::regexp 
=> 0 

Điều đó đang được nói, như xa như tôi biết, Ruby không có một cách mặc định để phân tích cú pháp URL, vì vậy nhiều khả năng bạn sẽ cần một viên ngọc để làm như vậy. Nếu bạn cần phải phù hợp URL cụ thể trong HTTP hoặc HTTPS định dạng, bạn có thể làm một cái gì đó như thế này:

uri = URI.parse(my_possible_url) 
if uri.kind_of?(URI::HTTP) or uri.kind_of?(URI::HTTPS) 
    # do your stuff 
end 
+2

Lần chỉnh sửa đầu tiên, hy vọng tôi đã trợ giúp và phù hợp: P – Philip

+0

@Philip Cả hai đều hữu ích và phù hợp. Cảm ơn nhiều! – fotanus

+1

'uri.kind_of? (URI :: HTTP)' có vẻ là đủ cho cả hai trường hợp (http và https), ít nhất là trong ruby ​​1.9.3. –

4

Nói chung,

/^#{URI::regexp}$/ 

sẽ làm việc tốt, nhưng nếu bạn chỉ muốn để phù hợp với http hoặc https, bạn có thể vượt qua những người trong như các tùy chọn để phương pháp:

/^#{URI::regexp(%w(http https))}$/ 

Đó có xu hướng làm việc tốt hơn một chút, nếu bạn muốn từ chối các giao thức như ftp://.

3

Đối với tôi, tôi sử dụng biểu thức chính quy này:

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

Tùy chọn:

  • i - case insensitive
  • x - bỏ qua khoảng trắng trong regex

Bạn có thể đặt phương pháp này để kiểm tra xác thực URL:

def valid_url?(url) 
    url_regexp = /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix 
    url =~ url_regexp ? true : false 
end 

Để sử dụng nó:

valid_url?("http://stackoverflow.com/questions/1805761/check-if-url-is-valid-ruby") 

Testing với URL sai:

  • http://ruby3arabi - kết quả là không hợp lệ
  • http://http://ruby3arabi.com - kết quả là không hợp lệ
  • http:// - kết quả là không hợp lệ

Thử nghiệm với URL chính xác:

  • http://ruby3arabi.com - kết quả có giá trị
  • http://www.ruby3arabi.com - kết quả có giá trị
  • https://www.ruby3arabi.com - kết quả có giá trị
  • https://www.ruby3arabi.com/article/1 - kết quả có giá trị
  • https://www.ruby3arabi.com/websites/58e212ff6d275e4bf9000000?locale=en - Kết quả hợp lệ
Các vấn đề liên quan