2011-07-12 16 views
11

En Ruby tengo una cadena arbitraria, y me gustaría convertirla en algo que sea un nombre de archivo válido para Unix/Linux. No importa cómo se ve en su forma final, siempre y cuando sea visualmente reconocible como la cadena con la que comenzó. Algunos ejemplos posibles:Convertir cadena de Ruby a * nix cadena compatible con el nombre de archivo

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

¿hay algo incorporado (tal vez en las bibliotecas de archivos) que va a lograr esto (o cerca de este)?

+0

En la mayoría de los sistemas de archivos Linux, los únicos caracteres no permitidos en los nombres de archivo son '\ 0' y'/'. '* es un asterisco, ves 'es un nombre de archivo perfectamente válido. – sepp2k

+0

@ sepp2k: Buen punto. En ese caso, quiero hacer un archivo que sea posible que alguien mueva o elimine sin sacarse todo el pelo :) – jrdioko

Respuesta

18

Según sus especificaciones, puede lograr esto con un reemplazo de regex. Esta expresión regular coincidirá con todos los caracteres que no sean letras básicas y dígitos:

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

Esto eliminará cualquier espacio en blanco extra entre palabras, como se muestra en los ejemplos:

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

Y, por último, vuelva a colocar el resto de espacios con guiones:

s/\s+/_/g 

Aquí está en Rubí:

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

Gracias. ¿Por qué es necesaria la "i" en el primer 'gsub'? – jrdioko

+0

Oh, no lo es. Pensé que '\ w' correspondía solo a' [a-z0-9] 'pero en realidad es' [a-zA-Z0-9] '. Gracias por señalar eso. Editaré mi respuesta. –

+0

Esto también elimina el. (punto) entre el nombre de archivo y su extensión – JoshL

2

Primero, veo que se me preguntó puramente en ruby, y segundo que no es el mismo propósito (* nix filename compatible), pero si está utilizando Rails, hay un método llamado parameterize que debería ayudar.

En los carriles de la consola:

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

creo que parametrizar, por ser compatible con las especificaciones de URL, puede trabajar también con los nombres de archivo :)

se puede ver más por aquí: http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-parameterize

También hay muchos otros métodos útiles.