【问题标题】:Replacing illegal character in fileName替换文件名中的非法字符
【发布时间】:2013-02-11 02:57:27
【问题描述】:

在 Java 中,我有一个文件名字符串。我想用'_'替换所有非法字符,但不是a-z0-9-._

我尝试了以下代码:但这不起作用!

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

【问题讨论】:

  • 由于标题比实际问题更笼统,我对这个问题的解决方案是使用filename = URLEncoder(fileName, "UTF-8") 作为文件名。此操作的结果始终是有效的文件名。这也允许在文件名上使用URLDecoder 获取原始文件名字符
  • 无法保证生成的文件名始终有效。 * 不是有效字符。
  • 文件名 = URLEncoder(fileName.replaceAll("\\*","%2A"), "UTF-8");

标签: java regex replace


【解决方案1】:

您需要替换除[a-zA-Z0-9.-] 之外的所有内容。 括号中的^ 代表“NOT”。

myString = myString.replaceAll("[^a-zA-Z0-9\\.\\-]", "_");

【讨论】:

  • @bbholzbb 我不这么认为。
  • 我知道范围尚未明确定义,但有效字符远不止 0-9 和 a-z。外语呢?对于 Windows,请参阅 msdn.microsoft.com/en-us/library/windows/desktop/…
  • 其他 UTF-8 字符呢?我是说其他语言?
  • 你真的应该在发布之前测试你的代码...... .- 都必须被转义!我设法让这个正则表达式工作:[^a-zA-Z0-9_\\-\\.]
  • @Erk "在大多数正则表达式风格中,字符类中唯一的特殊字符或元字符是右括号 (])、反斜杠 (\)、插入符号 (^) 和连字符 ( -)。通常的元字符是字符类中的普通字符,不需要用反斜杠转义。要搜索星号或加号,请使用 [+*]。如果您转义常规元字符,您的正则表达式将正常工作在字符类中,但这样做会大大降低可读性。” regular-expressions.info
【解决方案2】:

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

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

【讨论】:

  • 您可以用全角对应字符替换非法字符:/\\:*?"<>|
  • 抱歉,正则表达式实际上应该是 4x 反斜杠而不是 2x 吗?例如:"[\\\\/:*?\"&lt;&gt;|]"
  • 另一组替换字符 ” ‹ › ⁎ ∕ ⑊ \︖ ꞉ ⏐
【解决方案3】:

保持简单。

myString = myString.replaceAll("[^a-zA-Z0-9.-]", "_");

http://ideone.com/TINsr4

【讨论】:

  • 我没有投反对票,但可能是因为有一个类似的答案和更好的 (?) 解释。
  • 是否有任何可用的 java API 可以解决这个问题?由于进一步的兼容性问题。我的意思是这种手动替换可能会在 Windows 以外的其他环境中产生一些错误。
  • @rajper 不是 AFAIK。最简单的就是确定你想支持的所有平台上所有非法字符的集合,然后全部替换掉​​。
【解决方案4】:

更简单

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

预定义的字符类:

  • \w一字字:[a-zA-Z_0-9]

【讨论】:

    【解决方案5】:

    我知道这里已经有一些答案,但我想指出我必须稍微改变给定的建议。

    filename.matches("^.*[^a-zA-Z0-9._-].*$")
    

    这是我必须在 Java 中使用 .matches 来获得所需的结果。我不确定这是否 100% 正确,但这就是它对我的工作方式,如果遇到 az AZ 0-9 (.) (_) 和 (-) 以外的任何字符,它将返回 true。

    我想知道我这里的逻辑是否有任何缺陷。

    在以前的答案中,我看到了一些关于应该或不应该逃避什么的讨论。对于这个例子,我没有转义任何东西,但你应该转义 (-) 减号字符以确保安全,因为它会“破坏”你的表达式,除非它位于列表的末尾。 (.) 点字符不必在看起来像的 ([]) 方括号内转义,但如果您转义它不会对您造成伤害。

    请参阅 Java Patterns 了解更多详情。

    【讨论】:

      【解决方案6】:

      如果你想使用更多像[A-Za-z0-9],那么检查MS Naming Conventions,并且不要忘记过滤掉“......整数表示在1到31范围内的字符, ...”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多