362 votes

Transformer une chaîne en un nom de fichier valide en Python

J'ai une chaîne que je veux utiliser comme nom de fichier, donc je veux supprimer tous les caractères qui ne sont pas autorisés dans les noms de fichiers à l'aide de Python.

Je serais plutôt stricte que dans d'autres cas, disons que je veux conserver uniquement des lettres, des chiffres, et une série d'autres personnages comme "_-.() ". Quelle est la solution la plus élégante?

Le nom de fichier doit être valide sur plusieurs systèmes d'exploitation (Windows, Linux et Mac OS) - c'est un fichier MP3 dans ma bibliothèque, avec le titre de la chanson que le nom de fichier, et est partagée et soutenue entre les 3 machines.

216voto

S.Lott Points 207588

Vous pouvez regarder le framework Django pour savoir comment ils créent un "slug" à partir de texte arbitraire. Un slug est compatible avec les URL et les noms de fichiers.

Leur template/defaultfilters.py (autour de la ligne 183) définit une fonction, slugify , c'est probablement l'étalon-or pour ce genre de chose. Essentiellement, leur code est le suivant.

 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())
    ... re.sub('[-\s]+', '-', value)
 

Il y a plus, mais je l'ai laissé de côté, car il ne traite pas de slugification, mais s'échappe.

108voto

Vinko Vrsalovic Points 116138

Cette approche par liste blanche (c'est à dire, en autorisant uniquement les caractères présents dans valid_chars) ne fonctionnera que si il n'y a pas de limites sur le formatage des fichiers ou de la combinaison de caractères valides, illégales (comme le ".."), par exemple, ce que vous dites permettrait un nom de fichier nommé " . txt", qui je pense n'est pas valide sur Windows. Comme c'est le plus simple d'approche que j'allais essayer de supprimer l'espace de la valid_chars et ajouter un connu chaîne valide en cas d'erreur, toute autre approche devez savoir à propos de ce qui est permis, où pour faire face à Windows de nommage des fichiers de limites et donc d'être beaucoup plus complexe.

>>> 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'

107voto

Igal Serban Points 7058

Quelle est la raison d'utiliser les chaînes comme noms de fichiers? Si la lisibilité humaine n'est pas un facteur j'irais avec le module base64 qui peut produire des chaînes de sécurité du système de fichiers. Ce ne sera pas lisible, mais vous ne devrez pas faire face à des collisions et il est réversible.

 import base64
file_name_string = base64.urlsafe_b64encode(your_string)
 

Mise à jour : modifié en fonction du commentaire de Matthew.

43voto

Brian Points 48423

Juste pour compliquer les choses, vous n'êtes pas assuré d'obtenir un nom de fichier valide par simple suppression des caractères non valides. Depuis permis de caractères diffèrent sur un nom de fichier différent, une approche conservatrice pourrait tourner un nom valide dans une réserve non valide. Vous pouvez ajouter un traitement spécial pour le cas où:

  • La chaîne est tous des caractères non valides (vous laissant avec une chaîne vide)

  • Vous vous retrouvez avec une chaîne de caractères ayant une signification spéciale, par exemple,". " ou ".."

  • Sur windows, certains noms de périphériques sont réservés. Par exemple, vous ne pouvez pas créer un fichier nommé "nul", "nul.txt" (ou nul.rien, en fait), Les noms réservés sont:

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

Vous pouvez probablement contourner ces problèmes en ajoutant une chaîne de caractères pour les noms de fichiers qui ne peut jamais entraîner dans un de ces cas, et le décapage des caractères non valides.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X