如何检查字符串是否是有效的URL?
例如:
http://hello.it => yes
http:||bra.ziz, => no
如果这是一个有效的URL,如何检查它是否与图像文件有关?
如何检查字符串是否是有效的URL?
例如:
http://hello.it => yes
http:||bra.ziz, => no
如果这是一个有效的URL,如何检查它是否与图像文件有关?
Answers:
使用URI
随Ruby一起分发的模块:
require 'uri'
if url =~ URI::regexp
# Correct URL
end
就像AlexanderGünther在评论中说的那样,它检查字符串是否包含 URL。
要检查字符串是否为URL,请使用:
url =~ /\A#{URI::regexp}\z/
如果您只想检查Web 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相反,这将使URL无效 URI.regexp
出于某种原因允许使用空格。
我最近发现了为不同的URI rgexps提供的快捷方式。您可以URI::DEFAULT_PARSER.regexp.keys
直接从中访问URI::#{key}
。
例如,:ABS_URI
可以从访问regexp URI::ABS_URI
。
/^#{URI.regexp}$/
。麻烦在于,这种URI.regexp
锚不固定。带有空格的字符串不会将空格作为URI的一部分进行验证,而是导致空格的所有内容。如果该片段看起来像有效的URI,则匹配成功。
'http://:5984/asdf' =~ URI::DEFAULT_PARSER.regexp[:ABS_URI]
给出0,而不是nil;'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。
URI可以进一步分类为定位符,名称或两者。术语“统一资源定位符”(URL)指的是URI的子集,除了标识资源外,它还通过描述资源的主要访问机制(例如,其网络“位置”)提供了一种定位资源的方式。
由于URL是URI的子集,因此很明显,专门为URI进行的匹配将成功匹配不需要的值。例如,URN:
"urn:isbn:0451450523" =~ URI::regexp
=> 0
话虽如此,据我所知,Ruby没有解析URL的默认方法,因此您很可能需要使用gem来进行解析。如果您需要以HTTP或HTTPS格式专门匹配URL,则可以执行以下操作:
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)
至少在ruby 1.9.3中,这两种情况(http和https)似乎都足够。
URI.parse(string_to_be_checked).kind_of?(URI::HTTP)
做得很好。
我更喜欢可寻址宝石。我发现它可以更智能地处理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)
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")
使用错误的网址进行测试:
http://ruby3arabi
-结果无效http://http://ruby3arabi.com
-结果无效http://
-结果无效使用正确的网址进行测试:
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
-结果有效这有点旧了,但是这就是我的做法。使用Ruby的URI模块来解析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答案。对我来说,我不在乎,所以很理想。
您也可以使用正则表达式,例如http://www.geekzilla.co.uk/View2D3B0109-C1B2-4B4E-BFFD-E8088CBC85FD.htm假设此正则表达式正确(我尚未完全检查),则以下内容将显示网址的有效性。
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
可以做的事实际上已被破坏。请参阅上面众多建议的答案下的评论。不确定珍妮的答案是否正确,但希望如此,人们希望它能更认真地考虑。我最终要做的url.start_with?("http://") || url.start_with?("https://")
是TBH,因为我只需要HTTP,并且用户应该负责使用正确的URL。