Похоже, это не работает: 'http://:5984/asdf' =~ URI::regexpи 'http::5984/asdf' =~ URI::regexpоба возвращают 0. Я ожидал, что они вернут nil, потому что ни один из них не является допустимым URI.
awendt
4
Разве нет: 5984 порт 5984 на локальном хосте?
mxcl 07
3
Фактически он проверяет, содержит ли переменная действительный URL-адрес. Он примет " example com" как действительный URL. Потому что он содержит один. Но это бесполезно, если вы ожидаете, что все это будет URL-адресом.
Александр Гюнтер
2
gotqn: Это не действительный URL согласно RFC 1738.
Mikael S
12
Не используйте это, это так плохо, что "http:"проходит это регулярное выражение.
smathy
43
Как и в ответах выше, я считаю, что это регулярное выражение немного более точное:
URI::DEFAULT_PARSER.regexp[:ABS_URI]
Это сделает недействительными URL-адреса с пробелами, в отличие от тех, URI.regexpкоторые по какой-то причине допускают пробелы.
Недавно я нашел ярлык, который предоставляется для различных URI rgexps. Вы можете получить доступ к любому из URI::DEFAULT_PARSER.regexp.keysфайлов прямо из URI::#{key}.
Например, к :ABS_URIрегулярному выражению можно получить доступ из URI::ABS_URI.
Если вы планируете использовать URI.parse в любой момент, это определенно лучший вариант. URI :: regexp соответствует определенным URL-адресам, которые не работают при последующем использовании URI.parse. Спасибо за чаевые.
markquezada
К сожалению, это доступно только на Ruby 1.9, но не на 1.8.
Стив Мэдсен,
1
Но это работает: /^#{URI.regexp}$/. Проблема в том, что URI.regexpэто не якорь. Строка с пробелом не проверяет пробел как часть URI, но все, что ведет к пробелу. Если этот фрагмент выглядит как действительный URI, совпадение считается успешным.
Стив Мэдсен,
3
Применение комментария Авендта к вашим предложениям: 'http://:5984/asdf' =~ URI::DEFAULT_PARSER.regexp[:ABS_URI]дает 0, а не ноль; 'http::5984/asdf'=~ URI::DEFAULT_PARSER.regexp[:ABS_URI]дает 0; 'http://:5984/asdf' =~ /^#{URI.regexp}$/дает 0; 'http::5984/asdf' =~ /^#{URI.regexp}$/также дает 0. Ни одно из вышеперечисленных регулярных выражений не является полностью правильным, однако они не работают только в очень странных ситуациях, и в большинстве случаев это не имеет большого значения.
URI можно дополнительно классифицировать как указатель, имя или и то, и другое. Термин «унифицированный указатель ресурса» (URL) относится к подмножеству идентификаторов URI, которые, помимо идентификации ресурса, предоставляют средства определения местоположения ресурса путем описания его основного механизма доступа (например, его сетевого «местоположения»).
Поскольку URL-адреса являются подмножеством URI, ясно, что сопоставление специально для URI будет успешно соответствовать нежелательным значениям. Например, URN :
"urn:isbn:0451450523" =~ URI::regexp
=> 0
При этом, насколько мне известно, в Ruby нет способа по умолчанию для анализа URL-адресов, поэтому для этого вам, скорее всего, понадобится гем. Если вам нужно сопоставить URL-адреса конкретно в формате HTTP или HTTPS, вы можете сделать что-то вроде этого:
uri = URI.parse(my_possible_url)
if uri.kind_of?(URI::HTTP) or uri.kind_of?(URI::HTTPS)
# do your stuffend
uri.kind_of?(URI::HTTP)кажется достаточным для обоих случаев (http и https), по крайней мере, в ruby 1.9.3.
Андреа Саличетти
все еще страдает от проблем, описанных @skalee в ответе
jonuts
1
Резюме, URI.parse(string_to_be_checked).kind_of?(URI::HTTP)делает свою работу хорошо.
Бен
Кроме того, из-за очень частой опечатки в нашей базе данных люди часто ставят много слэшей:, http:///neopets.comчто, к сожалению, также верно. Это исправляет проверка наличия имени хоста:uri = URI(str) ; %w[http https].include?(uri.scheme) && !uri.host.nil?
Шейн
19
Я предпочитаю Addressable gem . Я обнаружил, что он обрабатывает URL-адреса более разумно.
Я просто загрузил в Addressable :: URI.parse () самые странные строки, чтобы увидеть, что он отклоняет. Он принимал безумные вещи. Однако первая строка, которую он не принял, была «:-)». Хм.
mvw
1
Как за это так много голосов? Addressable::URI.parseне возвращает nil с недопустимым вводом.
garbagecollector
11
Это довольно старая запись, но я решил пойти дальше и внести свой вклад:
Это работает намного лучше, чем приведенные выше решения. Он не имеет перечисленных выше предостережений, а также не принимает uris, например javascript: alert ('spam').
bchurchill
2
но он также совпадает http:/, что может быть не тем, что вам нужно.
Следующее помечено как действительное:, "http://test.com\n<script src=\"nasty.js\">"и любой домен, который использует один из 683 TLD , длина которого превышает 5 символов, или имеет два или более последовательных дефиса, помечается как недопустимый. Допускаются номера портов вне диапазона 0-65535. FTP и IP-адреса явно запрещены, но стоит отметить.
aidan
1
это просто лучшее, наиболее применимое решение для быстрой проверки URL. спасибо
somedirection
4
Это немного устарело, но вот как я это делаю. Используйте модуль URI Ruby для анализа URL-адреса. Если его можно проанализировать, значит, это действительный URL. (Но это не значит, что доступно.)
URI поддерживает множество схем, плюс вы можете добавлять собственные схемы самостоятельно:
Я столкнулся с этим, пытаясь исправить ошибку сегментации. На URI.parseсамом деле причиной этого было использование в Ruby 2.5.5 - я переключился на ответ @jonuts ниже, если вы не возражаете против некоторых странных случаев, которые могут произойти. Для моих целей мне было все равно, так что это было идеально.
el n00b,
3
В общем,
/^#{URI::regexp}$/
будет работать хорошо, но если вы хотите только сопоставить httpили https, вы можете передать их как параметры методу:
/^#{URI::regexp(%w(http https))}$/
Это работает немного лучше, если вы хотите отклонить такие протоколы, как ftp://.
А как насчет схемы mailto? Или telnet, gopher, nntp, rsync, ssh или какие-то другие схемы? URL-адреса немного сложнее, чем просто HTTP и FTP.
mu слишком короткое
Написать регулярное выражение для проверки URL-адресов сложно. Зачем беспокоиться?
Rimian
@Rimian, ты должен потрудиться, потому что все, что URIможно сделать, фактически сломано. Смотрите комментарии под столькими ответами, за которые проголосовали выше. Не уверен, что ответ Джени правильный, но, надеюсь, люди воспринимают его более серьезно. TBH Я в конечном итоге делаю это, url.start_with?("http://") || url.start_with?("https://")потому что мне нужен только HTTP, и пользователи должны нести ответственность за использование правильных URL-адресов.
Ответы:
Используйте
URI
модуль, поставляемый с Ruby:require 'uri' if url =~ URI::regexp # Correct URL end
Как сказал Александр Гюнтер в комментариях, он проверяет, содержит ли строка URL.
Для того, чтобы проверить , если строка является URL - адрес, использование:
url =~ /\A#{URI::regexp}\z/
Если вы хотите проверить только веб-URL (
http
илиhttps
), используйте это:url =~ /\A#{URI::regexp(['http', 'https'])}\z/
источник
'http://:5984/asdf' =~ URI::regexp
и'http::5984/asdf' =~ URI::regexp
оба возвращают 0. Я ожидал, что они вернут nil, потому что ни один из них не является допустимым URI."http:"
проходит это регулярное выражение.Как и в ответах выше, я считаю, что это регулярное выражение немного более точное:
URI::DEFAULT_PARSER.regexp[:ABS_URI]
Это сделает недействительными URL-адреса с пробелами, в отличие от тех,
URI.regexp
которые по какой-то причине допускают пробелы.Недавно я нашел ярлык, который предоставляется для различных URI rgexps. Вы можете получить доступ к любому из
URI::DEFAULT_PARSER.regexp.keys
файлов прямо изURI::#{key}
.Например, к
:ABS_URI
регулярному выражению можно получить доступ изURI::ABS_URI
.источник
/^#{URI.regexp}$/
. Проблема в том, чтоURI.regexp
это не якорь. Строка с пробелом не проверяет пробел как часть URI, но все, что ведет к пробелу. Если этот фрагмент выглядит как действительный URI, совпадение считается успешным.'http://:5984/asdf' =~ URI::DEFAULT_PARSER.regexp[:ABS_URI]
дает 0, а не ноль;'http::5984/asdf'=~ URI::DEFAULT_PARSER.regexp[:ABS_URI]
дает 0;'http://:5984/asdf' =~ /^#{URI.regexp}$/
дает 0;'http::5984/asdf' =~ /^#{URI.regexp}$/
также дает 0. Ни одно из вышеперечисленных регулярных выражений не является полностью правильным, однако они не работают только в очень странных ситуациях, и в большинстве случаев это не имеет большого значения.URI::DEFAULT_PARSER.regexp[:ABS_URI]
идентично/\A\s*#{URI::regexp}\s*\z/
Проблема с текущими ответами заключается в том, что URI не является URL-адресом .
Поскольку URL-адреса являются подмножеством URI, ясно, что сопоставление специально для URI будет успешно соответствовать нежелательным значениям. Например, URN :
"urn:isbn:0451450523" =~ URI::regexp => 0
При этом, насколько мне известно, в Ruby нет способа по умолчанию для анализа URL-адресов, поэтому для этого вам, скорее всего, понадобится гем. Если вам нужно сопоставить URL-адреса конкретно в формате HTTP или HTTPS, вы можете сделать что-то вроде этого:
uri = URI.parse(my_possible_url) if uri.kind_of?(URI::HTTP) or uri.kind_of?(URI::HTTPS) # do your stuff end
источник
uri.kind_of?(URI::HTTP)
кажется достаточным для обоих случаев (http и https), по крайней мере, в ruby 1.9.3.URI.parse(string_to_be_checked).kind_of?(URI::HTTP)
делает свою работу хорошо.http:///neopets.com
что, к сожалению, также верно. Это исправляет проверка наличия имени хоста:uri = URI(str) ; %w[http https].include?(uri.scheme) && !uri.host.nil?
Я предпочитаю Addressable gem . Я обнаружил, что он обрабатывает 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
источник
Addressable::URI.parse
не возвращает nil с недопустимым вводом.Это довольно старая запись, но я решил пойти дальше и внести свой вклад:
String.class_eval do def is_valid_url? uri = URI.parse self uri.kind_of? URI::HTTP rescue URI::InvalidURIError false end end
Теперь вы можете сделать что-то вроде:
if "http://www.omg.wtf".is_valid_url? p "huzzah!" end
источник
http:/
, что может быть не тем, что вам нужно.Для меня я использую это регулярное выражение:
/^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix
Вариант:
i
- без учета регистраx
- игнорировать пробелы в регулярном выраженииВы можете установить этот метод для проверки валидации 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
Чтобы использовать это:
valid_url?("http://stackoverflow.com/questions/1805761/check-if-url-is-valid-ruby")
Тестирование с неправильными URL-адресами:
http://ruby3arabi
- результат неверныйhttp://http://ruby3arabi.com
- результат неверныйhttp://
- результат неверныйhttp://test.com\n<script src=\"nasty.js\">
(Просто отметьте «<скрипт»)Протестируйте с правильными URL-адресами:
http://ruby3arabi.com
- результат действительныйhttp://www.ruby3arabi.com
- результат действительныйhttps://www.ruby3arabi.com
- результат действительныйhttps://www.ruby3arabi.com/article/1
- результат действительныйhttps://www.ruby3arabi.com/websites/58e212ff6d275e4bf9000000?locale=en
- результат действительныйисточник
"http://test.com\n<script src=\"nasty.js\">"
и любой домен, который использует один из 683 TLD , длина которого превышает 5 символов, или имеет два или более последовательных дефиса, помечается как недопустимый. Допускаются номера портов вне диапазона 0-65535. FTP и IP-адреса явно запрещены, но стоит отметить.Это немного устарело, но вот как я это делаю. Используйте модуль URI Ruby для анализа URL-адреса. Если его можно проанализировать, значит, это действительный URL. (Но это не значит, что доступно.)
URI поддерживает множество схем, плюс вы можете добавлять собственные схемы самостоятельно:
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}
См. Документацию для получения дополнительной информации о модуле URI.
источник
URI.parse
самом деле причиной этого было использование в Ruby 2.5.5 - я переключился на ответ @jonuts ниже, если вы не возражаете против некоторых странных случаев, которые могут произойти. Для моих целей мне было все равно, так что это было идеально.В общем,
/^#{URI::regexp}$/
будет работать хорошо, но если вы хотите только сопоставить
http
илиhttps
, вы можете передать их как параметры методу:/^#{URI::regexp(%w(http https))}$/
Это работает немного лучше, если вы хотите отклонить такие протоколы, как
ftp://
.источник
Вы также можете использовать регулярное выражение, возможно, что-то вроде http://www.geekzilla.co.uk/View2D3B0109-C1B2-4B4E-BFFD-E8088CBC85FD.htm при условии, что это регулярное выражение правильное (я не полностью его проверил), следующее будет показать действительность 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 }
Приведенный выше пример выводит:
http://hello.it is valid http:||bra.ziz not valid
источник
URI
можно сделать, фактически сломано. Смотрите комментарии под столькими ответами, за которые проголосовали выше. Не уверен, что ответ Джени правильный, но, надеюсь, люди воспринимают его более серьезно. TBH Я в конечном итоге делаю это,url.start_with?("http://") || url.start_with?("https://")
потому что мне нужен только HTTP, и пользователи должны нести ответственность за использование правильных URL-адресов.