Python string.replace () no reemplaza caracteres

Alguna información de fondo: Tenemos un antiguo sistema de base de datos de documentos en la web donde trabajo, que consiste casi en documentos de MS Office con las extensiones “normales” (.doc, .xls, .ppt). Todos se nombran en función de algún tipo de número de identificación arbitrario (es decir, 1245.doc). Estamos cambiando a SharePoint y necesito cambiar el nombre de todos estos archivos y ordenarlos en carpetas. Tengo un archivo CSV con todo tipo de información (como el número de identificación que corresponde al título del documento), así que lo estoy usando para cambiar el nombre de estos archivos. He escrito una breve secuencia de comandos de Python que cambia el nombre del título del número de ID.

Sin embargo, algunos de los títulos de los documentos tienen barras diagonales y otros caracteres posiblemente malos en el título de un archivo, por lo que quiero reemplazarlos con guiones bajos:

bad_characters = ["/", "\\", ":", "(", ")", "", "|", "?", "*"] for letter in bad_characters: filename = line[2].replace(letter, "_") foldername = line[5].replace(letter, "_") 
  • Ejemplo de la line[2] : “Blah blah aburrido – reunión 2/19 / 2008.doc”
  • Ejemplo de la line[5] : “Reuniones de negocios 2/2008”

Cuando agrego print letter dentro del bucle for , se imprimirá la letra que se supone que está reemplazando, pero en realidad no reemplazará ese carácter con un guión bajo como quiero.

¿Hay algo que estoy haciendo mal aquí?

Esto se debe a que el filename y la foldername se foldername con cada iteración del bucle. El método .replace() devuelve una cadena, pero no está guardando el resultado en ninguna parte.

Deberías usar:

 filename = line[2] foldername = line[5] for letter in bad_characters: filename = filename.replace(letter, "_") foldername = foldername.replace(letter, "_") 

Pero lo haría usando expresiones regulares. Es más limpio y (probablemente) más rápido:

 p = re.compile('[/:()<>|?*]|(\\\)') filename = p.sub('_', line[2]) folder = p.sub('_', line[5]) 

Está reasignando las variables de filename y filename foldername en cada iteración del bucle. En efecto, solo se está reemplazando * .

Debes mirar el método de la cadena python translate() http://docs.python.org/library/string.html#string.translate con http://docs.python.org/library/string.html#string.maketrans

Editando esto para agregar un ejemplo según la sugerencia de comentario a continuación:

 import string toreplace=''.join(["/", "\\", ":", "(", ")", "<", ">", "|", "?", "*"]) underscore=''.join( ['_'] * len(toreplace)) transtable = string.maketrans(toreplace,underscore) filename = filename.translate(transtable) foldername = foldername.translate(transtable) 

Se puede simplificar al hacer que el toreplace sea algo como ‘/ \ :,’, etc., simplemente utilicé lo que se dio anteriormente.

Está comenzando de nuevo con la línea base en lugar de guardar el resultado reemplazado, por lo tanto, obtiene el equivalente a

 filename = line[2].replace('*', '_') foldername = line[5].replace('*', '_') 

Intenta lo siguiente

 bad_characters = ["/", "\\", ":", "(", ")", "<", ">", "|", "?", "*"] filename = line[2] foldername = line[5] for letter in bad_characters: filename = filename.replace(letter, "_") foldername = foldername.replace(letter, "_") 

Debería usar string.replace (str, fromStr, toStr)

 bad_characters = ["/", "\\", ":", "(", ")", "<", ">", "|", "?", "*"] for letter in bad_characters: filename = string.replace(line[2], letter, "_") foldername = string.replace(line[5], letter, "_")