[python] 문자열을 유효한 파일 이름으로 바꾸시겠습니까?

파일 이름으로 사용하려는 문자열이 있으므로 Python을 사용하여 파일 이름에 허용되지 않는 모든 문자를 제거하고 싶습니다.

다른 방법보다 엄격하기 때문에 문자, 숫자 및와 같은 작은 다른 문자 집합 만 유지하고 싶다고 가정 해 봅시다 "_-.() ". 가장 우아한 솔루션은 무엇입니까?

파일 이름은 여러 운영 체제 (Windows, Linux 및 Mac OS)에서 유효해야합니다. 파일 이름이 노래 제목 인 내 라이브러리의 MP3 파일이며 3 대의 컴퓨터간에 공유 및 백업됩니다.



답변

Django 프레임 워크 에서 임의의 텍스트로 “슬러그”를 만드는 방법을 살펴볼 수 있습니다 . 슬러그는 URL 및 파일 이름 친화적입니다.

Django 텍스트 유틸리티는 함수를 정의합니다. slugify()아마도 이런 종류의 표준 일 것입니다. 기본적으로 코드는 다음과 같습니다.

def slugify(value):
    """
    Normalizes string, converts to lowercase, removes non-alpha characters,
    and converts spaces to hyphens.
    """
    import unicodedata
    value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
    value = unicode(re.sub('[^\w\s-]', '', value).strip().lower())
    value = unicode(re.sub('[-\s]+', '-', value))
    # ...
    return value

더 많은 것이 있지만, 제련을 다루지 않고 탈출하기 때문에 제외했습니다.


답변

이 화이트리스트 방식 (즉, valid_chars에있는 문자 만 허용)은 파일 형식이나 “..”와 같이 잘못된 유효한 문자 조합 (예 : “..”)에 제한이없는 경우 작동합니다. Windows에서 유효하지 않다고 생각되는 “.txt”라는 파일 이름을 허용합니다. 이것이 가장 간단한 접근법이므로 valid_chars에서 공백을 제거하고 오류가 발생하는 경우 알려진 유효한 문자열을 추가하려고 시도하므로 다른 접근법은 Windows 파일 명명 제한 에 대처할 수있는 위치에 대해 알아야 하므로 따라서 훨씬 더 복잡합니다.

>>> import string
>>> valid_chars = "-_.() %s%s" % (string.ascii_letters, string.digits)
>>> valid_chars
'-_.() abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
>>> filename = "This Is a (valid) - filename%$&$ .txt"
>>> ''.join(c for c in filename if c in valid_chars)
'This Is a (valid) - filename .txt'


답변

문자열 메서드와 함께 목록 이해를 사용할 수 있습니다.

>>> s
'foo-bar#baz?qux@127/\\9]'
>>> "".join(x for x in s if x.isalnum())
'foobarbazqux1279'


답변

문자열을 파일 이름으로 사용하는 이유는 무엇입니까? 사람의 가독성이 중요하지 않은 경우 파일 시스템 안전 문자열을 생성 할 수있는 base64 모듈을 사용합니다. 읽을 수는 없지만 충돌을 처리 할 필요가 없으며 가역적입니다.

import base64
file_name_string = base64.urlsafe_b64encode(your_string)

업데이트 : Matthew의 의견에 따라 변경되었습니다.


답변

더 복잡하게 만들기 위해 잘못된 문자를 제거하여 유효한 파일 이름을 얻을 수는 없습니다. 허용되는 문자는 파일 이름이 다르기 때문에 보수적 인 접근 방식으로 인해 유효한 이름을 잘못된 이름으로 바꿀 수 있습니다. 다음과 같은 경우에 특별한 처리를 추가 할 수 있습니다.

  • 문자열은 모두 유효하지 않은 문자입니다 (빈 문자열로 남겨 두십시오)

  • “.”와 같은 특별한 의미의 문자열로 끝납니다. 또는 “..”

  • Windows에서는 특정 장치 이름 이 예약되어 있습니다. 예를 들어 “nul”, “nul.txt”(또는 실제로 nul.anything)라는 파일을 만들 수 없습니다. 예약 된 이름은 다음과 같습니다.

    CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, ​​COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8 및 LPT9

파일 이름 앞에 문자열을 추가하여 이러한 경우 중 하나를 초래할 수 없으며 유효하지 않은 문자를 제거하여 이러한 문제를 해결할 수 있습니다.


답변

Github에는 python-slugify 라는 멋진 프로젝트가 있습니다 .

설치:

pip install python-slugify

그런 다음 사용하십시오.

>>> from slugify import slugify
>>> txt = "This\ is/ a%#$ test ---"
>>> slugify(txt)
'this-is-a-test'


답변

S.Lott 가 대답 한 것처럼 Django Framework 에서 문자열을 유효한 파일 이름으로 변환하는 방법을 볼 수 있습니다 .

최신 및 업데이트 된 버전은 utils / text.py에 있으며 “get_valid_filename”을 정의합니다.

def get_valid_filename(s):
    s = str(s).strip().replace(' ', '_')
    return re.sub(r'(?u)[^-\w.]', '', s)

( https://github.com/django/django/blob/master/django/utils/text.py 참조 )