Создать (вменяемое/безопасное) имя файла из любой (небезопасной) строки

Я хочу создать нормальное / безопасное имя файла(т. е. несколько читаемое, без "странных" символов и т. д.) из какой-то случайной строки Unicode (mich может содержать что угодно).

(для меня не имеет значения, является ли функция Cocoa, ObjC, Python и т. д.)


конечно, может быть бесконечное множество символов, которые могут быть странными. Таким образом, это не решение иметь черный список и добавлять все больше и больше в этот список с течением времени.

I может быть белый список. Однако я не знаю, как это определить. [a-zA-Z0-9 .] - Это начало, но я также хочу принять символы unicode, которые могут отображаться обычным способом.

6 ответов


Python:

"".join([c for c in filename if c.isalpha() or c.isdigit() or c==' ']).rstrip()

это принимает символы Юникода, но удаляет разрывы строк и т. д.

пример:

filename = u"ad\nbla'{-+\)(ç?"

выдает: adblaç

редактировать .айсалкым() не буквенно-цифровых на один шаг. - комментарий от queueoverflow ниже. danodonovan намекнул на сохранении с точкой.

    keepcharacters = (' ','.','_')
    "".join(c for c in filename if c.isalnum() or c in keepcharacters).rstrip()

мои требования были консервативными (сгенерированные имена файлов должны быть действительны в нескольких операционных системах, включая некоторые древние мобильные ОС ). Я закончил:

    "".join([c for c in text if re.match(r'\w', c)])

этот белый список буквенно-цифровых символов (a-z, A-Z, 0-9 ) и подчеркивания. Регулярное выражение может быть скомпилировано и кэшировано для эффективности, если необходимо сопоставить много строк. В моем случае это не имело бы никакого значения.


здесь нет решений, только проблемы, которые вы должны рассмотреть:

  • какова ваша минимальная максимальная длина имени файла? (например, DOS поддерживает только 8-11 символов; большинство ОС не поддерживают >256 символов)

  • какие имена файлов запрещены в некотором контексте? (Windows по-прежнему не поддерживает сохранение файла как CON.TXT -- см.https://blogs.msdn.microsoft.com/oldnewthing/20031022-00/?p=42073)

  • запомнить это . и .. имеют определенные значения (текущий/родительский каталог) и поэтому небезопасны.

  • есть ли риск, что имена файлов столкнутся - либо из-за удаления символов, либо одно и то же имя файла используется несколько раз?

рассмотрим просто хэширование данных и использование hexdump этого в качестве имени файла?


Python:

for c in r'[]/\;,><&*:%=+@!#^()|?^':
    filename = filename.replace(c,'')

(просто пример символов, которые вы хотите удалить) The r перед строкой убедитесь, что строка интерпретируется в формате raw, что позволяет удалить обратную косую черту \ а также

изменить: решение regex в Python:

import re
re.sub(r'[]/\;,><&*:%=+@!#^()|?^', '', filename)

def make_safe_filename(s):
    def safe_char(c):
        if c.isalnum():
            return c
        else:
            return "_"
    return "".join(safe_char(c) for c in s).rstrip("_")

print(make_safe_filename( "hello you crazy $#^#& 2579 people!!! : die!!!" ) + ".gif")

гравюры:

Привет_ты _ сумасшедший_______2579 _ человек______умри___.gif


более или менее то, что было упомянуто здесь с regexp, но в обратном порядке (замените любые не перечисленные):

>>> import re
>>> filename = u"ad\nbla'{-+\)(ç1?"
>>> re.sub(r'[^\w\d-]','_',filename)
u'ad_bla__-_____1_'