如何可逆地转义Ruby中的URL,以便将其保存到文件系统中

时间:2013-08-14 14:44:07

标签: ruby string file

用例示例将http://example.com的内容保存为您计算机上的文件名,但不安全的字符(即:/)已转义。

经典的方法是使用正则表达式删除所有非字母数字 - 破折号下划线字符,但这样就无法将文件名反转为URL。有没有办法,可能是CGI.escape和另一个过滤器的组合来清理Windows和* nix的文件名?即使权衡是一个更长的文件名?

编辑:

CGI.escape

的示例
 CGI.escape 'http://www.example.com/Hey/whatsup/1 2 3.html#hash'
 #=> "http%3A%2F%2Fwww.example.com%2FHey%2Fwhatsup%2F1+2+3.html%23hash"

有几件事...... %标志是完全安全的文件字符吗?遗憾的是,CGI.escape在第一次传递时未将格式错误的网址中的空格转换为%20,因此我认为任何翻译方法都需要将+的所有空格更改为gsub然后然后应用CGI.escape

2 个答案:

答案 0 :(得分:3)

其中一种方法是“散列”文件名。例如,此问题的网址为:https://stackoverflow.com/questions/18234870/how-to-reversibly-escape-a-url-in-ruby-so-that-it-can-be-saved-to-the-file-syste。您可以使用Ruby标准库的digest/md5库来对名称进行哈希处理。简单而优雅。

require "digest/md5"

foldername = "https://stackoverflow.com/questions/18234870/how-to-reversibly-escape-a-url-in-ruby-so-that-it-can-be-saved-to-the-file-syste"
hashed_name = Digest::MD5.hexdigest(foldername) # => "5045cccd83a8d4d5c4fc01f7b4d8c502"

此方案的必然结果是MD5哈希用于验证下载的真实性/完整性,因为对于所有实际目的,字符串的MD5摘要始终返回相同的十六进制字符串。

但是,我不会称之为“可逆”。您需要使用自定义方法来查找生成的每个哈希的URL。可能是包含该数据的.yml文件。


更新:正如@the Tin Man建议的那样,当存在大量需要存储的文件时,简单的SQLite数据库会比.yml文件好得多。

答案 1 :(得分:2)

这是我将如何做(根据需要调整正则表达式):

url = "http://stackoverflow.com/questions/18234870/how-to-reversibly-escape-a-url-in-ruby-so-that-it-can-be-saved-to-the-file-syste"
filename = url.each_char.map {|x|
  x.match(/[a-zA-Z0-9-]/) ? x : "_#{x.unpack('H*')[0]}"
}.join

编辑:

如果生成的文件名的长度是一个问题,那么我会将这些文件存储在子目录中,其名称与url路径段相同。