有没有办法合并我用来将多平台文件路径转换为URL的这两个正则表达式?
@image_file = "#{request.protocol}#{request.host}/#{@image_file.path.sub(/^([a-z]):\//,"")}".sub(/^\//,"")
这会处理我的Windows和* IX平台,以便将文件路径转换为URL。例如,以下两个文件路径字符串都已正确处理:
- "c:\users\docs\pictures\image.jpg" goes to "http://localhost/users/docs/pictures/image.jpg"
- "\home\usr_name\pictures\image.jpg" goes to "http://localhost/usr_name/pictures/image.jpg"
如果有方法可以正确组合它,我宁愿不必对字符串使用两个sub
调用。
欢迎社区的建议和反馈!
答案 0 :(得分:2)
您正在寻找的正则表达式是/^([a-z]:)?\//
:
"c:/users/docs/pictures/image.jpg".sub(/^([a-z]:)?\//, '')
=> "users/docs/pictures/image.jpg"
"/home/usr_name/pictures/image.jpg".sub(/^([a-z]:)?\//, '')
=> "home/usr_name/pictures/image.jpg"
答案 1 :(得分:0)
作为处理文件名和URL的一些背景......
首先,Ruby不要求你在Windows文件名中使用反斜杠,所以如果你生成它们就不要打扰了。相反,依赖于IO类知道您所使用的操作系统这一事实,并将自动检测路径分隔符并为您即时转换内容。这来自the IO documentation:
如果可能,Ruby将在不同的操作系统约定之间转换路径名。例如,在Windows系统上,文件名“/gumby/ruby/test.rb”将打开为“\ gumby \ ruby \ test.rb”。在Ruby字符串中指定Windows样式的文件名时,请记住转义反斜杠:"c:\\gumby\\ruby\\test.rb"
我们这里的例子将使用Unix风格的正斜杠; File :: ALT_SEPARATOR可用于获取特定于平台的分隔符。
如果您正在接收来自其他来源的路径,这可以很容易地将它们规范化为Ruby喜欢的东西:
path = "c:\\users\\docs\\pictures\\image.jpg" # => "c:\\users\\docs\\pictures\\image.jpg"
puts path
# >> c:\users\docs\pictures\image.jpg
path.gsub!(/\\/, '/') if path['\\']
path # => "c:/users/docs/pictures/image.jpg"
puts path
# >> c:/users/docs/pictures/image.jpg
为方便起见,编写一个小帮手方法:
def normalize_path(p)
p.gsub(/\\/, '/')
end
normalize_path("c:\\users\\docs\\pictures\\image.jpg") # => "c:/users/docs/pictures/image.jpg"
normalize_path("/users/docs/pictures/image.jpg") # => "/users/docs/pictures/image.jpg"
Ruby的File和Pathname类在处理路径时非常有用:
foo = normalize_path(path) # => "c:/users/docs/pictures/image.jpg"
File.dirname(foo) # => "c:/users/docs/pictures"
File.basename(foo) # => "image.jpg"
和
File.split(foo) # => ["c:/users/docs/pictures", "image.jpg"]
path_to_file, filename = File.split(foo)
path_to_file # => "c:/users/docs/pictures"
filename # => "image.jpg"
另外还有Pathname类:
require 'pathname'
bar = Pathname.new(foo)
bar.dirname # => #<Pathname:c:/users/docs/pictures>
bar.basename # => #<Pathname:image.jpg>
Pathname是Ruby标准库中的一个实验类,它将File,FileUtils和Dir中的所有便捷方法包装成一个伞类。值得了解一下:
这个类的目标是以比标准Ruby提供的更简洁的方式操作文件路径信息。以下示例说明了不同之处。
包括File,FileTest以及Dir和FileUtils中的一些功能,这是一种不足为奇的方式。它本质上是所有这些的外观,甚至更多。
回到你的问题......
Ruby的标准库也包含URI类。它经过了很好的测试,并且是一种比简单的字符串连接更好的构建URL的方法,因为当需要对字符进行编码时可能会发生这种特性。
require 'uri'
url = URI::HTTP.build({:host => 'www.foo.com', :path => foo[/^(?:[a-z]:)?(.+)/, 1]})
url # => #<URI::HTTP:0x007fe91117a438 URL:http://www.foo.com/users/docs/pictures/image.jpg>
build
方法应用语法规则以确保URL有效。
如果您需要它,此时您可以使用to_s
来获取字符串化版本:
url.to_s # => "http://www.foo.com/users/docs/pictures/image.jpg"