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

75 投票
13 回答
63946 浏览
提问于 2025-04-17 02:13

我想从一些随机的Unicode字符串中创建一个合理安全的文件名(也就是说,文件名要能看懂,不要有“奇怪”的字符等等)。

我对使用什么编程语言(比如Cocoa、ObjC、Python等)都没什么特别要求。


当然,可能有无数个字符是奇怪的。因此,单靠列出一个黑名单,随着时间的推移不断添加更多字符,并不是一个真正的解决办法。

我可以考虑使用白名单。不过,我不太知道该怎么定义这个白名单。[a-zA-Z0-9 .]是一个开始,但我还想接受那些可以正常显示的Unicode字符。

13 个回答

13

这里提到的内容大致是关于正则表达式的,不过是反过来的意思(替换掉任何未列出的内容):

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

我的要求比较保守(生成的文件名需要在多个操作系统上有效,包括一些古老的手机操作系统)。最后我得到了:

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

这个代码列出了可以使用的字符,包括字母(a-z,A-Z)和数字(0-9),还有下划线。这个正则表达式可以编译并缓存,以提高效率,特别是当需要匹配很多字符串的时候。不过对我来说,这样做并没有什么显著的区别。

96

Python:

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

撰写回答