Немного справочной информации: у нас есть древняя веб-система баз документов, где я работаю, почти полностью состоящая из документов MS Office с «обычными» расширениями (.doc, .xls, .ppt). Все они названы на основе своего рода произвольного идентификационного номера (то есть 1245.doc). Мы переходим на SharePoint, и мне нужно переименовать все эти файлы и отсортировать их по папкам. У меня есть файл CSV со всеми видами информации (например, какой идентификационный номер соответствует названию какого документа), поэтому я использую его для переименования этих файлов. Я написал короткий скрипт Python, который переименовывает заголовок идентификационного номера.

Однако некоторые заголовки документов имеют косую черту и другие, возможно, плохие символы в заголовке файла, поэтому я хочу заменить их подчеркиванием:

bad_characters = ["/", "\\", ":", "(", ")", "<", ">", "|", "?", "*"]
for letter in bad_characters:
    filename = line[2].replace(letter, "_")
    foldername = line[5].replace(letter, "_")
  • Пример line[2]: "Бла-бла-скучный - встреча 2/19 / 2008.doc"
  • Пример line[5]: "Деловые встречи 2/2008"

Когда я добавляю print letter внутри цикла for, он выводит букву, которую он должен заменить, но на самом деле не заменяет этот символ подчеркиванием, как я этого хочу.

Что я здесь делаю не так?

13
ZeroUptime 19 Авг 2010 в 18:57

5 ответов

Лучший ответ

Это потому, что filename и foldername выбрасываются при каждой итерации цикла. Метод .replace() возвращает строку, но вы нигде не сохраняете результат.

Вам следует использовать:

filename = line[2]
foldername = line[5]

for letter in bad_characters:
    filename = filename.replace(letter, "_")
    foldername = foldername.replace(letter, "_")

Но я бы сделал это с помощью регулярных выражений. Это чище и (скорее всего) быстрее:

p = re.compile('[/:()<>|?*]|(\\\)')
filename = p.sub('_', line[2])
folder = p.sub('_', line[5])
26
NullUserException 12 Ноя 2012 в 01:53

Вы начинаете заново с базовой строки вместо сохранения замененного результата, таким образом, вы получаете эквивалент

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

Попробуйте следующее

bad_characters = ["/", "\\", ":", "(", ")", "<", ">", "|", "?", "*"]
filename = line[2]
foldername = line[5]
for letter in bad_characters:
    filename = filename.replace(letter, "_")
    foldername = foldername.replace(letter, "_")
3
Kathy Van Stone 19 Авг 2010 в 15:05

Вы переназначаете переменные filename и foldername на каждой итерации цикла. Фактически заменяется только *.

6
Vebjorn Ljosa 19 Авг 2010 в 15:01

Вы должны взглянуть на метод строки Python translate() http://docs.python.org/library/string.html#string. переводить с http://docs.python.org/library/string.html#string. maketrans

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

Можно упростить, сделав toreplace что-то вроде '/ \ :,' и т. Д., Я просто использовал то, что было дано выше

4
Amala 19 Авг 2010 в 19:53

Следует использовать string.replace (str, fromStr, toStr)

bad_characters = ["/", "\\", ":", "(", ")", "<", ">", "|", "?", "*"]
for letter in bad_characters:
    filename = string.replace(line[2], letter, "_")
    foldername = string.replace(line[5], letter, "_")
1
wu liang 18 Авг 2011 в 16:20