2010-08-19 19 views
11

Algunos antecedentes: Tenemos un antiguo sistema de base de datos documental basado en la web en la que trabajo, que consiste casi en su totalidad de los documentos de MS Office con las extensiones "normales" (.doc, .xls, .ppt). Todos se nombran según algún tipo de número de ID 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 la que corresponde el número de identificación a la que el título del documento), así que estoy usando para cambiar el nombre de estos archivos. Escribí un breve script de Python que cambia el nombre del título del número de ID.Python String.Replace() no reemplazar caracteres

Sin embargo, algunos de los títulos de los documentos tienen barras y otros caracteres, posiblemente, no es bueno tener en un título de un archivo, por lo que quiero reemplazarlos con guiones:

bad_characters = ["/", "\\", ":", "(", ")", "<", ">", "|", "?", "*"] 
for letter in bad_characters: 
    filename = line[2].replace(letter, "_") 
    foldername = line[5].replace(letter, "_") 
  • Ejemplo de line[2] : "bla, bla aburrido - Reunión 2/19/2008.doc"
  • Ejemplo de line[5]: "Las reuniones de negocios 2/2008"

Cuando agrego print letter interior del bucle for, se imprimirá la carta que se supone que debe reemplazar, pero en realidad no reemplazará ese personaje con un guión como yo quiero que haga.

¿Hay algo que estoy haciendo mal aquí?

+2

Pregunta tangencial: ¿ha considerado hacer esto con una expresión regular? –

+0

@todos - Gracias por las explicaciones. No puedo creer que lo haya pasado por alto. (jueves ...) – ZeroUptime

Respuesta

23

Esto se debe a que filename y foldername se descartan con cada iteración del ciclo. El método .replace() devuelve una cadena, pero no estás almacenando el resultado en cualquier lugar.

Deberá utilizar:

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]) 
+0

Puede haber una razón para no cambiar la línea [2] y la línea [5] –

+0

@Kathy Buen punto, respuesta fija – NullUserException

6

Usted está reasignando a las variables filename y foldername en cada iteración del ciclo. En efecto, solo se está reemplazando *.

4

Usted debe mirar el método de cadena pitón translate() http://docs.python.org/library/string.html#string.translate con http://docs.python.org/library/string.html#string.maketrans

Edición de esto para añadir un ejemplo según el comentario sugerencia a continuación:
import string 
toreplace=''.join(["/", "\\", ":", "(", ")", "<", ">", "|", "?", "*"]) 
underscore=''.join(['_'] * len(toreplace)) 
transtable = string.maketrans(toreplace,underscore) 
filename = filename.translate(transtable) 
foldername = foldername.translate(transtable) 

puede simplificar haciendo que el toreplace algo así como '/ \ :,' etc, acabo de utilizar lo que fue dado por encima de

+0

¿podría dar un ejemplo en el contexto actual? – iamgopal

3

usted está comenzando de nuevo con la línea de base en lugar de guardar el resultado reemplazado, por lo que está recibiendo el equivalente a

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

intente lo siguiente

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

En caso de utilizar cuerdas.reemplazar (str, fromStr, toStr)

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