Java使用正则表达式来提取文件名

时间:2011-10-10 08:26:06

标签: java regex

我需要从文件的绝对路径获取文件名(我知道file.getName()方法,但我不能在这里使用它)。 编辑:我不能使用file.getName(),因为我不需要文件名;我也需要文件路径的一部分(但同样,不是整个absoulte路径)。在提供某个路径之后,我需要文件路径的一部分。

假设该文件位于文件夹中:

C:\Users\someUser

在Windows机器上,如果我按如下方式创建一个模式字符串:

String patternStr = "C:\\Users\\someUser\\(.*+)";

我得到一个例外:java.util.regex.PatternSyntaxException: Illegal/unsupported escape sequence反斜杠。

如果我使用Pattern.quote(File.pathSeparator):

String patternStr = "C:" + Pattern.quote(File.separator) + "Users" + Pattern.quote(File.separator) + "someUser" + Pattern.quote(File.separator) + "(.*+)";

生成的模式字符串是:C:\Q;\EUsers\Q;\EsomeUser\Q;\E(.*+)当然与实际fileName“C:\ Users \ someUser \ myFile.txt”不匹配。

我在这里缺少什么?解析文件名的正确方法是什么?

10 个答案:

答案 0 :(得分:7)

  

解析文件名的正确方法是什么?

解析文件名的正确方法是使用File(String)。使用正则表达式可以将平台依赖项硬连接到代码中。这是一个坏主意。

我知道你说你不能使用File.getName() ......但那是正确的解决方案。如果你想说明为什么你不能使用File.getName()或许我可以提出另一种解决方案。

答案 1 :(得分:4)

如果您确实想使用正则表达式,则应使用

String patternStr = "C:\\\\Users\\\\someUser\\\\(.*+)";
                       ^^       ^^          ^^

代替。

为什么呢?你的字符串文字

"C:\\Users\\someUser\\(.*+)"

编译为

C:\Users\someUser\(.*+)

由于\也用于在正则表达式中进行转义,因此您必须“两次”转义它们。


关于您的修改:

您可能想查看URI.relativize()。例如:

File base = new File("C:/Users/someUser");
File file = new File("C:/Users/someUser/someDir/someFile.txt");

String relativePath = base.toURI().relativize(file.toURI()).getPath();

System.out.println(relativePath); // prints "someDir/someFile.txt"

(请注意,/在Windows计算机上也可用作文件分隔符。)


顺便说一下,我不知道你的系统上File.separator有什么,但是如果它设置为\,那么

"C:" + Pattern.quote(File.separator) + "Users" + Pattern.quote(File.separator) +
    "someUser" + Pattern.quote(File.separator) + "(.*+)";

应该产生

C:\Q\\EUsers\Q\\EsomeUser\Q\\E(.*+)

答案 2 :(得分:2)

String patternStr = "C:\\Users\\someUser\\(.*+)";

反斜杠(\)是Java语言中的转义字符。编译后,您的字符串包含以下内容:

C:\Users\someUser\(.*+)

然后将此字符串解析为正则表达式,它也使用反斜杠作为转义字符。正则表达式解析器尝试了解转义的\U\s\(。其中一个关于正则表达式语法是错误的(因此你的例外),并且它们都不是你想要实现的。

尝试

String patternStr = "C:\\\\Users\\\\someUser\\\\(.*+)";

答案 3 :(得分:1)

如果你想通过模式解决它,你需要正确地逃避你的模式

String patternStr = "C:\\\\Users\\\\someUser\\\\(.*+)";

答案 4 :(得分:0)

尝试在模式中加入双倍反斜杠。你需要第二个反斜杠来逃避模式中的一个,而且你需要加倍每一个以在字符串中逃避它们。因此,你最终会得到类似的东西:

String patternStr = "C:\\\\Users\\\\someUser\\\\(.*+)";

答案 5 :(得分:0)

从字符串的结尾移动到第一次出现的文件路径分隔符*或开始。

文件路径分隔符可以是/\

public static final char ALTERNATIVE_DIRECTORY_SEPARATOR_CHAR = '/';
public static final char DIRECTORY_SEPARATOR_CHAR = '\\';
public static final char VOLUME_SEPARATOR_CHAR = ':';


    public static String getFileName(String path) {

        if(path == null || path.isEmpty()) {
            return path;
        }

        int length = path.length();
        int index = length;

        while(--index >= 0) {

            char c = path.charAt(index);

            if(c == ALTERNATIVE_DIRECTORY_SEPARATOR_CHAR || c == DIRECTORY_SEPARATOR_CHAR || c == VOLUME_SEPARATOR_CHAR) {
                return path.substring(index + 1, length); 
            }
        }

        return path;
    }

尽量保持简单; - )。

答案 6 :(得分:0)

试试这个:

String ResultString = null;
try {
    Pattern regex = Pattern.compile("([^\\\\/:*?\"<>|\r\n]+$)");
    Matcher regexMatcher = regex.matcher(subjectString);
    if (regexMatcher.find()) {
        ResultString = regexMatcher.group(1);
    } 
} catch (PatternSyntaxException ex) {
    // Syntax error in the regular expression
}

输出:

myFile.txt

也适用于输入:C:/Users/someUser/myFile.txt

输出:myFile.txt

答案 7 :(得分:0)

  

我在这里缺少什么?解析文件名的正确方法是什么?

解析文件名的正确方法是使用已为此目的提供的API。您已声明无法使用File.getName(),无需解释。你几乎肯定是错的。

答案 8 :(得分:0)

  

我不能使用file.getName()因为我不需要文件名;我也需要文件路径的一部分(但同样,不是整个absoulte路径)。

行。所以你想要的是这样的。

    // Canonicalize paths to deal with ".", "..", symlinks, 
    // relative files and case sensitivity issues.
    String directory = new File(someDirectory).canonicalPath();
    String test = new File(somePathname).canonicalPath();

    if (!directory.endsWith(File.separator)) {
        directory += File.separator;
    }
    if (test.startsWith(directory)) {
        String pathInDirectory = test.substring(directory.length()):
        ...
    }

优点:

  • 不需要正则表达式。
  • 如果路径分隔符不是\
  • ,则不会中断
  • 如果路径上有符号链接,则不会中断。
  • 由于区分大小写问题而不会中断。

答案 9 :(得分:0)

假设文件名具有特殊字符,特别是在支持特殊字符允许的文件名的MAC时,服务器端Path.GetFileName(fileName)失败并因路径中的非法字符而引发错误。以下使用正则表达式的代码来救援。

以下正则表达式处理2件事

  1. 在IE中,上传文件时,文件路径也包含文件夹(即c:\ samplefolder \ subfolder \ sample.xls)。下面的表达式将用空字符串替换所有文件夹并保留文件名

  2. 在Mac中使用时,文件名是唯一提供的Safari浏览器并允许文件名中的特殊字符

     var regExpDir = @"(^[\w]:\\)([\w].+\w\\)";
    
     var fileName = Regex.Replace(fileName, regExpDir, string.Empty);