正则表达式替换Windows在文件名中不接受的字符

时间:2009-04-16 00:23:26

标签: java regex

我正在尝试构建一个正则表达式,它将检测Windows不接受的任何字符作为文件名的一部分(这些对于其他操作系统是否相同?我不知道,说实话)。

这些符号是:

 \ / : * ? "  | 

无论如何,这就是我所拥有的:[\\/:*?\"<>|]

http://gskinner.com/RegExr/处的测试人员表明这是有效的。 对于字符串Allo*ha*符号会亮起,表示已找到它。但是,如果我输入Allo**ha,则只有第一个*会亮起。所以我想我需要修改这个正则表达式以找到所提到的字符的所有外观,但我不确定。

你看,在Java中,我很幸运能拥有String.replaceAll(String regex, String replacement)函数。 描述说:

  

将此字符串中与给定正则表达式匹配的每个子字符串替换为给定的替换。

换句话说,即使正则表达式只找到第一个然后停止搜索,这个函数仍然会找到它们。

例如:String.replaceAll("[\\/:*?\"<>|]","")

但是,我觉得我不能冒这个风险。那么有人知道如何扩展它吗?

11 个答案:

答案 0 :(得分:17)

因为答案不够好我自己做了。希望这会有所帮助;)

public static boolean validateFileName(String fileName) {
    return fileName.matches("^[^.\\\\/:*?\"<>|]?[^\\\\/:*?\"<>|]*") 
    && getValidFileName(fileName).length()>0;
}

public static String getValidFileName(String fileName) {
    String newFileName = fileName.replace("^\\.+", "").replaceAll("[\\\\/:*?\"<>|]", "");
    if(newFileName.length()==0)
        throw new IllegalStateException(
                "File Name " + fileName + " results in a empty fileName!");
    return newFileName;
}

答案 1 :(得分:14)

Windows文件名规则棘手。你只是摸不着头脑。

例如,除了列出的字符外,这里还有一些无效的文件名:

                                    (yes, that's an empty string)
.
.a
a.
 a                                  (that's a leading space)
a                                   (or a trailing space)
com
prn.txt
[anything over 240 characters]
[any control characters]
[any non-ASCII chracters that don't fit in the system codepage,
 if the filesystem is FAT32]

删除像String.replaceAll()这样的单个正则表达式子句中的特殊字符是不够的;你可以很容易地得到一些无效的东西,如空字符串或尾随'。'或''。用“_”替换“[^ A-Za-z0-9 _。] *”之类的东西将是更好的第一步。但是你仍然需要在你正在使用的任何平台上进行更高级别的处理。

答案 2 :(得分:3)

我使用纯粹而简单的正则表达式。 我给出可能出现的字符,并通过否定“^”我改变所有其他字符作为这样的标志。 “_”

  

String fileName = someString.replaceAll(“[^ a-zA-Z0-9 \\。\\ - ]”,“_”);

例如: 如果你不想在表达式中使用“。”然后删除“\\。”

  

String fileName = someString.replaceAll(“[^ a-zA-Z0-9 \\ - ]”,“_”);

答案 3 :(得分:2)

对于记录,POSIX兼容系统(包括UNIX和Linux)支持除空字符('\0')之外的所有字符,并在文件名中转发斜杠('/')。必须在命令行中转义特殊字符(如空格和星号),以便它们不会执行常规角色。

答案 4 :(得分:1)

Java有一个replaceAll函数,但每种编程语言都有办法做类似的事情。例如,Perl使用g开关来表示全局替换。 Python的sub函数允许您指定要进行的替换次数。如果由于某种原因,您的语言没有具有等效语言,您可以随时执行以下操作:

while (filename.matches(bad_characters)
  filename.replace(bad_characters, "")

答案 5 :(得分:1)

我从原始字符串中提取所有单词字符和空白字符,并且还确保字符串末尾不存在空格字符。这是我在java中的代码片段。

temp_string = original.replaceAll("[^\\w|\\s]", "");
final_string = temp_string.replaceAll("\\s$", "");

我想我帮了别人。

答案 6 :(得分:0)

您可以尝试仅允许用户输入的内容,例如A-Z,a-z和0-9。

答案 7 :(得分:0)

您无法使用单个正则表达式执行此操作,因为正则表达式始终匹配输入时的子字符串。考虑单词Alo*h*a,没有包含所有* s的子字符串,而不包含任何其他字符。因此,如果您可以使用replaceAll函数,只需坚持使用它。

顺便说一下,禁止字符集在其他操作系统中是不同的。

答案 8 :(得分:0)

我制作了一个非常 简单的方法 ,适用于大多数常见情况:

// replace special characters that windows doesn't accept
private String replaceSpecialCharacters(String string) {
    return string.replaceAll("[\\*/\\\\!\\|:?<>]", "_")
            .replaceAll("(%22)", "_");
}
如果您的文件名中包含qoute(&#34; ),则

%22 会被编码。

答案 9 :(得分:0)

所需的正则表达式/语法(JS):

.trim().replace(/[\\/:*?\"<>|]/g,"").substring(0,240);

其中最后一位是可选的,仅在您希望将长度限制为240时使用。

其他有用的功能(JS):

.toUppperCase();
.toLowerCase();
.replace(/  /g,' ');     //normalising multiple spaces to one, add before substring.
.includes("str");        //check if a string segment is included in the filename
.split(".").slice(-1);   //get extension, given the entire filename contains a .

答案 10 :(得分:-1)

Windows也不接受&#34;%&#34;作为文件名。

如果您正在构建可能影响最终将移动到其他操作系统的文件的通用表达式,我建议您添加更多可能存在问题的字符。

例如,在Linux(我知道很多发行版)中,某些用户可能会遇到包含[b]&amp ;; ! ] [/ - ()[/ b]。这些符号在文件名中是允许的,但是它们可能需要由用户特别处理,并且某些程序存在由它们存在引起的错误。