jrdioko
jrdioko

Reputation: 33457

Convert Ruby string to *nix filename-compatible string

In Ruby I have an arbitrary string, and I'd like to convert it to something that is a valid Unix/Linux filename. It doesn't matter what it looks like in its final form, as long as it is visually recognizable as the string it started as. Some possible examples:

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

Is there anything built-in (maybe in the file libraries) that will accomplish this (or close to this)?

Upvotes: 12

Views: 5347

Answers (3)

Montells
Montells

Reputation: 6679

Use Zaru Gem.

Zaru.sanitize! "  what\ēver//wëird:user:înput:"
# => "whatēverwëirduserînput"

Zaru.sanitize!("* is an asterisk, you see")
# => " is an asterisk, you see" 

Upvotes: 0

Diogo K.
Diogo K.

Reputation: 156

First, I see that it was asked purely in ruby, and second that it's not the same purpose (*nix filename compatible), but if you are using Rails, there is a method called parameterize that should help.

In rails console:

"Here's my string!".parameterize => "here-s-my-string"
"* is an asterisk, you see".parameterize => "is-an-asterisk-you-see"

I think that parameterize, as being compliant with URL specifications, may work as well with filenames :)

You can see more about here: http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-parameterize

There's also a whole lot of another helpful methods.

Upvotes: 10

Jon Gauthier
Jon Gauthier

Reputation: 25572

By your specifications, you could accomplish this with a regex replacement. This regex will match all characters other than basic letters and digits:

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

This will remove any extra whitespace in between words, as shown in your examples:

s/(^|\b\s)\s+($|\s?\b)/\\1\\2/g

And lastly, replace the remaining spaces with underscores:

s/\s+/_/g

Here it is in Ruby:

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

Upvotes: 24

Related Questions