替换文件名中的非法字符

64
在Java中,我有一个文件名字符串。我想用'_'替换所有非法字符,但不包括a-z0-9-._。 我尝试了以下代码:但这没有起作用!
myString = myString.replaceAll("[\\W][^\\.][^-][^_]", "_");

3
标题比实际问题更普遍,我解决这个问题的方法是使用filename = URLEncoder(fileName, "UTF-8")来处理文件名。这个操作的结果始终是有效的文件名。这也可以使用URLDecoder来获取原始文件名字符。 - ApollonDigital
不能保证生成的文件名始终有效。*不是一个有效字符。 - Dmytro Ovdiienko
文件名 = URLEncoder(fileName.replaceAll("\*","%2A"), "UTF-8"); - Conete Cristian
6个回答

114
你需要替换除了[a-zA-Z0-9.-]以外的所有内容。方括号内的^表示“非”。
myString = myString.replaceAll("[^a-zA-Z0-9\\.\\-]", "_");

8
@bbholzbb 我不这么认为。 - poitroae
14
我知道范围没有很好地定义,但是除了0-9和a-z之外,还有很多其他有效的字符。那么外语呢?关于Windows,请参见http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx。 - paul
9
其他UTF-8字符怎么样?我指的是其他语言的字符? - ehsun7b
27
在发布代码之前,你真的应该测试它……需要转义 .-!我成功让这个正则表达式有效:[^a-zA-Z0-9_\\-\\.] - Erk
9
在大多数正则表达式语法中,字符类中唯一的特殊字符或元字符是右方括号 (])、反斜杠 (\)、尖号 (^)和连字符 (-)。常用的元字符在字符类内部被视为普通字符,不需要通过反斜杠进行转义。如果要搜索星号 () 或加号 (+),可以使用 [+]。虽然在字符类内部转义普通元字符可以使正则表达式正常工作,但这样做会显著降低可读性。 regular-expressions.info - DavidS
显示剩余13条评论

32

如果您正在Windows平台上寻找选项,那么您可以尝试以下解决方案,以利用文件名中除"\ /: *? <> |"之外的所有有效字符。

fileName = fileName.replaceAll("[\\\\/:*?\"<>|]", "_");

3
您可以用全角字符替换非法字符:/\\:*?"<>| - Juribiyan
1
抱歉,正则表达式实际上应该是4个反斜杠而不是2个吗?例如:"[\\\\/:*?\"<>|]" - kevinarpe
另一组替换字符 "‹›⁎∕⑊\︖꞉⏐" - aljgom

16

我没有投反对票,但可能是因为有一个更好的相似答案(?)解释了。 - nhahtdh
3
有没有可用的Java API来处理这个问题?由于进一步的兼容性问题,我是指手动替换可能会在除Windows以外的其他环境中产生一些错误。 - rogue lad
2
@rajper 不是我所知道的。最简单的方法是确定您想要支持的所有平台上的所有非法字符集,并将它们全部替换。 - Matt Ball

12

更加简单易懂

myString = myString.replaceAll("[^\\w.-]", "_");

预定义字符类:

  • \w 代表一个单词字符:[a-zA-Z_0-9]

2
我知道这里已经有一些答案了,但我想指出我不得不稍微修改给出的建议。
filename.matches("^.*[^a-zA-Z0-9._-].*$")

这是我在Java中使用.matches所需的内容,以获得所需的结果。我不确定这是否百分之百正确,但这就是它对我有用的方式,如果遇到除了a-z A-Z 0-9(.)(_)和(-)之外的任何字符,它将返回true。
我想知道我的逻辑是否存在任何缺陷。
在先前的答案中,我看到了一些关于应该或不应该转义的讨论。对于这个例子,我没有转义任何东西,但你应该转义(-)减号字符以确保安全,因为它会“破坏”你的表达式,除非它在列表的末尾。点字符(.)似乎不必在([])方括号内转义,但如果你转义它,也不会有害。
请参阅Java Patterns获取更多详细信息。

0

如果你想使用除了 [A-Za-z0-9] 以外的字符,那么请查看 MS 命名规范,并且不要忘记过滤掉“...整数表示在 1 到 31 范围内的字符...”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接