По вашим спецификациям, вы можете сделать это с помощью замены регулярных выражений.Это регулярное выражение будет соответствовать всем символам, кроме основных букв и цифр:
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