python字符串合法_python-从任何(不安全)字符串创建(合理/安全)文件名

python-从任何(不安全)字符串创建(合理/安全)文件名

我想从一些随机的Unicode字符串中创建一个合理/安全的文件名(即,可读性强,没有“奇怪”字符等)(某些文件可能只包含任何内容)。

(对于我来说,函数是否为Cocoa,ObjC,Python等都无所谓)

当然,可能有无数个可能很奇怪的字符。 因此,拥有黑名单并随着时间的推移将越来越多的黑名单添加到黑名单并不是真正的解决方案。

我可以有一个白名单。 但是,我真的不知道如何定义它。 [a-zA-Z0-9 .]是一个开始,但我也想接受可以正常显示的unicode字符。

7个解决方案

65 votes

蟒蛇:

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

这接受Unicode字符,但删除换行符等。

例:

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

给:adblaç

编辑str.isalnum()一步执行字母数字。 –来自下面的queueoverflow的评论。 danodonovan暗示要保留一个点。

keepcharacters = (' ','.','_')

"".join(c for c in filename if c.isalnum() or c in keepcharacters).rstrip()

Remi answered 2020-07-31T04:56:25Z

11 votes

我的要求很保守(生成的文件名必须在多个操作系统(包括某些古老的移动操作系统)上有效)。 我最终得到了:

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

该白色列出了字母数字字符(a-z,A-Z,0-9)和下划线。 如果要匹配很多字符串,则可以编译和缓存正则表达式以提高效率。 就我而言,这不会产生任何重大变化。

Ngure Nyaga answered 2020-07-31T04:56:50Z

6 votes

这里有一些合理的答案,但就我而言,我想采用的东西可能是带有空格和标点符号的字符串,而不仅仅是删除它们,我宁愿用下划线代替。 即使在大多数操作系统中,空格是允许的文件名字符,它们还是有问题的。 另外,在我的情况下,如果原始字符串包含句点,则我不希望该句点传递到文件名中,否则会生成我可能不希望的“额外扩展名”(我自己添加了扩展名)

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")

印刷品:

hello_you_crazy _______ 2579_people ______ die ___。gif

uglycoyote answered 2020-07-31T04:57:19Z

4 votes

正则表达式在这里或多或少提到了什么,但是相反(替换了未列出的任何东西):

>>> import re

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

>>> re.sub(r'[^\w\d-]','_',filename)

u'ad_bla__-_____1_'

Filipe Pina answered 2020-07-31T04:57:39Z

3 votes

这里没有解决方案,只有您必须考虑的问题:

您的最小最大文件名长度是多少? (例如,DOS仅支持8-11个字符;大多数操作系统不支持> 256个字符)

在某些情况下禁止使用什么文件名? (Windows仍然不支持将文件另存为2990266540295193193600-请参阅[https://blogs.msdn.microsoft.com/oldnewthing/20031022-00/?p=42073))

请记住,2990266540295193193600和2990266540295193193601具有特定含义(当前/父目录),因此不安全。

是否存在文件名冲突的风险-是由于删除了字符还是多次使用相同的文件名?

考虑仅对数据进行哈希处理并将其十六进制转储用作文件名吗?

Dragon answered 2020-07-31T04:58:22Z

2 votes

蟒蛇:

for c in r'[]/\;,>

filename = filename.replace(c,'')

(仅是您要删除的字符的示例)字符串前面的r确保字符串以原始格式解释,从而也可以删除反斜线\

编辑:Python中的正则表达式解决方案:

import re

re.sub(r'[]/\;,>

Remi answered 2020-07-31T04:58:51Z

0 votes

这是我受到uglycoyote启发而来的:

import time

def make_safe_filename(s):

def safe_char(c):

if c.isalnum() or c=='.':

return c

else:

return "_"

safe = ""

last_safe=False

for c in s:

if len(safe) > 200:

return safe + "_" + str(time.time_ns() // 1000000)

safe_c = safe_char(c)

curr_safe = c != safe_c

if not last_safe or not curr_safe:

safe += safe_c

last_safe=curr_safe

return safe

并测试:

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

Martin Kunc answered 2020-07-31T04:59:15Z

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值