将Ruby字符串转换为*nix文件名兼容的字符串

12

在Ruby中,我有一个任意字符串,并且我想将其转换为一个有效的Unix/Linux文件名。最终形式无所谓,只要它在视觉上可识别为最初的字符串即可。以下是一些可能的示例:

"Here's my string!" => "Heres_my_string"
"* is an asterisk, you see" => "is_an_asterisk_you_see"

有没有内置的东西(也许在文件库中)可以实现这个功能(或类似的功能)?

1
在大多数Linux文件系统中,文件名中唯一不允许的字符是\0/* is an asterisk, you see是一个完全有效的文件名。 - sepp2k
1
@sepp2k:说得好。在这种情况下,我想要创建一个文件,让别人可以轻松移动或删除,而不必拔光所有头发 :) - jrdioko
2个回答

23

根据您的要求,您可以通过正则表达式替换来实现此操作。 此正则表达式将匹配所有基本字母和数字以外的字符:

s/[^\w\s_-]+//g

这将删除单词之间的任何额外空格,就像您的示例中所示:
s/(^|\b\s)\s+($|\s?\b)/\\1\\2/g

最后,用下划线替换剩余的空格:
s/\s+/_/g

以下是 Ruby 代码示例:

def friendly_filename(filename)
    filename.gsub(/[^\w\s_-]+/, '')
            .gsub(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2')
            .gsub(/\s+/, '_')
end

谢谢。为什么在第一个 gsub 中需要 "i"? - jrdioko
哦,原来不是这样的。我以为\w只对应于[a-z0-9],但实际上它是[a-zA-Z0-9]。谢谢你指出来 - 我会编辑我的答案。 - Jon Gauthier
1
这也会移除文件名和扩展名之间的 .(句号)。 - JoshL
@JoshL 是的,缺少句点编码让我在这个正则表达式中吃了亏。希望有一个替代方案来保留句点作为另一个文件兼容字符以保持唯一性。 - Kelsey Hannan

9
首先,我看到这个问题是纯粹使用ruby提出的,其次它的目的不同于(*nix文件名兼容),但如果你正在使用Rails,有一个叫做parameterize的方法应该会有所帮助。
在rails控制台中:
"Here's my string!".parameterize => "here-s-my-string"
"* is an asterisk, you see".parameterize => "is-an-asterisk-you-see"

我认为参数化,作为符合URL规范的方式,可能也可以与文件名一起使用 :)
你可以在这里了解更多信息: http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-parameterize 还有很多其他有用的方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接