To wydaje się nie działać: 'http://:5984/asdf' =~ URI::regexpi 'http::5984/asdf' =~ URI::regexpoba zwracają 0. Spodziewałem się, że zwrócą nil, ponieważ żaden z nich nie jest prawidłowym identyfikatorem URI.
wendt
4
Czy nie jest: 5984 port 5984 na hoście lokalnym?
mxcl,
3
W rzeczywistości sprawdza, czy zmienna zawiera prawidłowy adres URL. Akceptuje „ example com” jako prawidłowy adres URL. Ponieważ zawiera jeden. Ale nie jest pomocne, jeśli oczekujesz, że całość będzie adresem URL.
Alexander Günther
2
gotqn: To nie jest jednak prawidłowy adres URL zgodnie z RFC 1738.
Mikael S
12
Nie używaj tego, jest tak źle, że "http:"przechodzi to wyrażenie regularne.
smathy,
43
Podobnie jak w przypadku powyższych odpowiedzi, uważam, że użycie tego wyrażenia regularnego jest nieco dokładniejsze:
URI::DEFAULT_PARSER.regexp[:ABS_URI]
Spowoduje to unieważnienie adresów URL ze spacjami, w przeciwieństwie do tego, URI.regexpco z jakiegoś powodu zezwala na spacje.
Niedawno znalazłem skrót, który jest dostępny dla różnych rgexps URI. Możesz uzyskać dostęp do dowolnego URI::DEFAULT_PARSER.regexp.keysbezpośrednio z URI::#{key}.
Na przykład do :ABS_URIwyrażenia regularnego można uzyskać dostęp z URI::ABS_URI.
Jeśli planujesz używać URI.parse w dowolnym momencie, jest to zdecydowanie najlepsza droga. URI :: regexp dopasowuje określone adresy URL, które zakończą się niepowodzeniem przy późniejszym użyciu URI.parse. Dzięki za wskazówkę.
markquezada
Niestety jest to dostępne tylko w Rubim 1.9, a nie 1.8.
Steve Madsen
1
Ale to działa: /^#{URI.regexp}$/. Problem w tym, URI.regexpże nie zakotwicza. Łańcuch ze spacją nie weryfikuje spacji jako części identyfikatora URI, ale wszystko, co prowadzi do spacji. Jeśli ten fragment wygląda jak prawidłowy identyfikator URI, dopasowanie powiedzie się.
Steve Madsen
3
Stosowanie komentarza awendt do twoich propozycji: 'http://:5984/asdf' =~ URI::DEFAULT_PARSER.regexp[:ABS_URI]daje 0, a nie zero; 'http::5984/asdf'=~ URI::DEFAULT_PARSER.regexp[:ABS_URI]daje 0; 'http://:5984/asdf' =~ /^#{URI.regexp}$/daje 0; 'http::5984/asdf' =~ /^#{URI.regexp}$/daje również 0. Żadne z powyższych wyrażeń regularnych nie jest w pełni poprawne, jednak zawodzą one tylko w bardzo dziwnych sytuacjach iw większości przypadków nie jest to wielka sprawa.
Identyfikator URI można dalej sklasyfikować jako lokalizator, nazwę lub jedno i drugie. Termin „Uniform Resource Locator” (URL) odnosi się do podzbioru identyfikatorów URI, które oprócz identyfikowania zasobu, umożliwiają zlokalizowanie zasobu poprzez opisanie jego głównego mechanizmu dostępu (np. „Lokalizacji” w sieci).
Ponieważ adresy URL są podzbiorem identyfikatorów URI, jasne jest, że dopasowanie specyficzne dla identyfikatorów URI z powodzeniem dopasuje niepożądane wartości. Na przykład URN :
"urn:isbn:0451450523" =~ URI::regexp
=> 0
Biorąc to pod uwagę, o ile wiem, Ruby nie ma domyślnego sposobu analizowania adresów URL, więc najprawdopodobniej będziesz potrzebować klejnotu, aby to zrobić. Jeśli potrzebujesz dopasować adresy URL konkretnie w formacie HTTP lub HTTPS, możesz zrobić coś takiego:
uri = URI.parse(my_possible_url)
if uri.kind_of?(URI::HTTP) or uri.kind_of?(URI::HTTPS)
# do your stuffend
Dodatkowo, bardzo częste błędy w wpisywaniu w naszej bazie danych pokazują, że ludzie mają tendencję do wstawiania wielu ukośników: http:///neopets.comco niestety jest również poprawne. Sprawdzanie obecności nazwy hosta rozwiązuje ten problem:uri = URI(str) ; %w[http https].include?(uri.scheme) && !uri.host.nil?
Shane
19
Wolę klejnot adresowalny . Odkryłem, że inteligentniej obsługuje adresy URL.
Właśnie podałem Addressable :: URI.parse () najdziwniejsze ciągi znaków, aby zobaczyć, co odrzuca. Akceptuje szalone rzeczy. Jednak pierwszym ciągiem, którego nie zaakceptował, był „:-)”. Hmm.
mvw
1
Jak to się dzieje, że dostaje tyle głosów za? Addressable::URI.parsenie zwraca nil z nieprawidłowymi danymi wejściowymi.
garbagecollector
11
To jest dość stary wpis, ale pomyślałem, że mogę się do tego przyczynić:
Działa to znacznie lepiej niż powyższe rozwiązania. Nie ma wymienionych powyżej zastrzeżeń, a także nie akceptuje adresów URL, takich jak javascript: alert ('spam').
bchurchill,
2
ale też pasuje http:/, co może nie być tym, czego chcesz.
Bo Jeanes
11
W moim przypadku używam tego wyrażenia regularnego:
Następujące elementy są oznaczone jako prawidłowe:, "http://test.com\n<script src=\"nasty.js\">"a każda domena, która używa jednej z 683 domen TLD dłuższych niż 5 znaków lub ma dwa lub więcej następujących po sobie myślników, jest oznaczana jako nieprawidłowa. Dozwolone są numery portów spoza zakresu 0-65535. Adresy FTP i IP są oczywiście niedozwolone, ale warto o tym pamiętać.
aidan
1
z łatwością najlepsze najbardziej odpowiednie rozwiązanie do szybkiego sprawdzania adresu URL. dzięki
jakimś kierunku
4
To jest trochę stare, ale oto jak to robię. Użyj modułu URI Ruby, aby przeanalizować adres URL. Jeśli można go przeanalizować, jest to prawidłowy adres URL. (Ale to nie znaczy, że jest dostępny).
URI obsługuje wiele schematów, a ponadto możesz samodzielnie dodawać schematy niestandardowe:
Natknąłem się na to próbując naprawić segfault. Używanie URI.parsebyło właściwie przyczyną tego w Rubim 2.5.5 - przełączyłem się na odpowiedź @jonuts poniżej, jeśli nie masz nic przeciwko niektórym dziwnym przypadkom. Dla moich celów nie obchodziło mnie to, więc to było idealne.
el n00b
3
Ogólnie,
/^#{URI::regexp}$/
będzie działać dobrze, ale jeśli chcesz tylko dopasować httplub httpsmożesz przekazać je jako opcje do metody:
/^#{URI::regexp(%w(http https))}$/
Zwykle działa to trochę lepiej, jeśli chcesz odrzucić protokoły takie jak ftp://.
A co z programem mailto? Lub telnet, gopher, nntp, rsync, ssh lub jakikolwiek inny schemat? Adresy URL są nieco bardziej skomplikowane niż tylko HTTP i FTP.
mu jest za krótkie
Pisanie wyrażenia regularnego w celu weryfikacji adresów URL jest trudne. Po co się męczyć?
Rimian
@Rimian, musisz się tym przejmować, ponieważ URIw rzeczywistości wszystko, co można zrobić, jest zepsute. Zobacz komentarze pod tak wieloma pozytywnymi odpowiedziami powyżej. Nie jestem pewien, czy odpowiedź Janie jest prawidłowa, ale głosowanie za głosem, więc mam nadzieję, że ludzie rozważą to poważniej. TBH w końcu robię, url.start_with?("http://") || url.start_with?("https://")ponieważ potrzebuję tylko HTTP, a użytkownicy powinni być odpowiedzialni za używanie odpowiednich adresów URL.
Odpowiedzi:
Użyj
URI
modułu dystrybuowanego z Rubim:require 'uri' if url =~ URI::regexp # Correct URL end
Jak Alexander Günther powiedział w komentarzach, sprawdza, czy ciąg zawiera adres URL.
Aby sprawdzić, czy ciąg jest adresem URL, użyj:
url =~ /\A#{URI::regexp}\z/
Jeśli chcesz sprawdzić tylko adresy internetowe (
http
lubhttps
), użyj tego:url =~ /\A#{URI::regexp(['http', 'https'])}\z/
źródło
'http://:5984/asdf' =~ URI::regexp
i'http::5984/asdf' =~ URI::regexp
oba zwracają 0. Spodziewałem się, że zwrócą nil, ponieważ żaden z nich nie jest prawidłowym identyfikatorem URI."http:"
przechodzi to wyrażenie regularne.Podobnie jak w przypadku powyższych odpowiedzi, uważam, że użycie tego wyrażenia regularnego jest nieco dokładniejsze:
URI::DEFAULT_PARSER.regexp[:ABS_URI]
Spowoduje to unieważnienie adresów URL ze spacjami, w przeciwieństwie do tego,
URI.regexp
co z jakiegoś powodu zezwala na spacje.Niedawno znalazłem skrót, który jest dostępny dla różnych rgexps URI. Możesz uzyskać dostęp do dowolnego
URI::DEFAULT_PARSER.regexp.keys
bezpośrednio zURI::#{key}
.Na przykład do
:ABS_URI
wyrażenia regularnego można uzyskać dostęp zURI::ABS_URI
.źródło
/^#{URI.regexp}$/
. Problem w tym,URI.regexp
że nie zakotwicza. Łańcuch ze spacją nie weryfikuje spacji jako części identyfikatora URI, ale wszystko, co prowadzi do spacji. Jeśli ten fragment wygląda jak prawidłowy identyfikator URI, dopasowanie powiedzie się.'http://:5984/asdf' =~ URI::DEFAULT_PARSER.regexp[:ABS_URI]
daje 0, a nie zero;'http::5984/asdf'=~ URI::DEFAULT_PARSER.regexp[:ABS_URI]
daje 0;'http://:5984/asdf' =~ /^#{URI.regexp}$/
daje 0;'http::5984/asdf' =~ /^#{URI.regexp}$/
daje również 0. Żadne z powyższych wyrażeń regularnych nie jest w pełni poprawne, jednak zawodzą one tylko w bardzo dziwnych sytuacjach iw większości przypadków nie jest to wielka sprawa.URI::DEFAULT_PARSER.regexp[:ABS_URI]
jest identyczne z/\A\s*#{URI::regexp}\s*\z/
Problem z obecnymi odpowiedziami polega na tym, że identyfikator URI nie jest adresem URL .
Ponieważ adresy URL są podzbiorem identyfikatorów URI, jasne jest, że dopasowanie specyficzne dla identyfikatorów URI z powodzeniem dopasuje niepożądane wartości. Na przykład URN :
"urn:isbn:0451450523" =~ URI::regexp => 0
Biorąc to pod uwagę, o ile wiem, Ruby nie ma domyślnego sposobu analizowania adresów URL, więc najprawdopodobniej będziesz potrzebować klejnotu, aby to zrobić. Jeśli potrzebujesz dopasować adresy URL konkretnie w formacie HTTP lub HTTPS, możesz zrobić coś takiego:
uri = URI.parse(my_possible_url) if uri.kind_of?(URI::HTTP) or uri.kind_of?(URI::HTTPS) # do your stuff end
źródło
uri.kind_of?(URI::HTTP)
wydaje się być wystarczający w obu przypadkach (http i https), przynajmniej w Rubim 1.9.3.URI.parse(string_to_be_checked).kind_of?(URI::HTTP)
działa dobrze.http:///neopets.com
co niestety jest również poprawne. Sprawdzanie obecności nazwy hosta rozwiązuje ten problem:uri = URI(str) ; %w[http https].include?(uri.scheme) && !uri.host.nil?
Wolę klejnot adresowalny . Odkryłem, że inteligentniej obsługuje adresy URL.
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
źródło
Addressable::URI.parse
nie zwraca nil z nieprawidłowymi danymi wejściowymi.To jest dość stary wpis, ale pomyślałem, że mogę się do tego przyczynić:
String.class_eval do def is_valid_url? uri = URI.parse self uri.kind_of? URI::HTTP rescue URI::InvalidURIError false end end
Teraz możesz zrobić coś takiego:
if "http://www.omg.wtf".is_valid_url? p "huzzah!" end
źródło
http:/
, co może nie być tym, czego chcesz.W moim przypadku używam tego wyrażenia regularnego:
/^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix
Opcja:
i
- bez rozróżniania wielkości literx
- zignoruj białe znaki w wyrażeniu regularnymMożesz ustawić tę metodę, aby sprawdzić poprawność adresu URL:
def valid_url?(url) return false if url.include?("<script") 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
Aby z niego skorzystać:
valid_url?("http://stackoverflow.com/questions/1805761/check-if-url-is-valid-ruby")
Testowanie z niewłaściwymi adresami URL:
http://ruby3arabi
- wynik jest nieprawidłowyhttp://http://ruby3arabi.com
- wynik jest nieprawidłowyhttp://
- wynik jest nieprawidłowyhttp://test.com\n<script src=\"nasty.js\">
(Po prostu zaznacz „<skrypt”)Przetestuj z poprawnymi adresami URL:
http://ruby3arabi.com
- wynik jest ważnyhttp://www.ruby3arabi.com
- wynik jest ważnyhttps://www.ruby3arabi.com
- wynik jest ważnyhttps://www.ruby3arabi.com/article/1
- wynik jest ważnyhttps://www.ruby3arabi.com/websites/58e212ff6d275e4bf9000000?locale=en
- wynik jest ważnyźródło
"http://test.com\n<script src=\"nasty.js\">"
a każda domena, która używa jednej z 683 domen TLD dłuższych niż 5 znaków lub ma dwa lub więcej następujących po sobie myślników, jest oznaczana jako nieprawidłowa. Dozwolone są numery portów spoza zakresu 0-65535. Adresy FTP i IP są oczywiście niedozwolone, ale warto o tym pamiętać.To jest trochę stare, ale oto jak to robię. Użyj modułu URI Ruby, aby przeanalizować adres URL. Jeśli można go przeanalizować, jest to prawidłowy adres URL. (Ale to nie znaczy, że jest dostępny).
URI obsługuje wiele schematów, a ponadto możesz samodzielnie dodawać schematy niestandardowe:
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}
Zobacz dokumentację, aby uzyskać więcej informacji o module URI.
źródło
URI.parse
było właściwie przyczyną tego w Rubim 2.5.5 - przełączyłem się na odpowiedź @jonuts poniżej, jeśli nie masz nic przeciwko niektórym dziwnym przypadkom. Dla moich celów nie obchodziło mnie to, więc to było idealne.Ogólnie,
/^#{URI::regexp}$/
będzie działać dobrze, ale jeśli chcesz tylko dopasować
http
lubhttps
możesz przekazać je jako opcje do metody:/^#{URI::regexp(%w(http https))}$/
Zwykle działa to trochę lepiej, jeśli chcesz odrzucić protokoły takie jak
ftp://
.źródło
Możesz również użyć wyrażenia regularnego, może coś takiego jak http://www.geekzilla.co.uk/View2D3B0109-C1B2-4B4E-BFFD-E8088CBC85FD.htm zakładając, że to wyrażenie regularne jest poprawne (nie sprawdziłem go w pełni). pokazać ważność adresu 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 }
Powyższy przykład daje:
http://hello.it is valid http:||bra.ziz not valid
źródło
URI
w rzeczywistości wszystko, co można zrobić, jest zepsute. Zobacz komentarze pod tak wieloma pozytywnymi odpowiedziami powyżej. Nie jestem pewien, czy odpowiedź Janie jest prawidłowa, ale głosowanie za głosem, więc mam nadzieję, że ludzie rozważą to poważniej. TBH w końcu robię,url.start_with?("http://") || url.start_with?("https://")
ponieważ potrzebuję tylko HTTP, a użytkownicy powinni być odpowiedzialni za używanie odpowiednich adresów URL.