【问题标题】:Java: Converting File Pattern to Regular Expression PatternJava:将文件模式转换为正则表达式模式
【发布时间】:2015-02-26 04:24:31
【问题描述】:

我正在尝试制作一个将文件模式转换为 java 正则表达式模式的实用程序函数,我需要它来对目录内的文件进行通配符匹配。我提出了 4 个需要考虑的案例。案例够不够?

    regexPattern = filePattern;
    // convert windows backslash to slash
    regexPattern = regexPattern.replace("\\", "/");
    // convert dot to \\.
    regexPattern = regexPattern.replace("\\.", "\\\\.z");
    // convert ? wildcard to .+
    regexPattern = regexPattern.replace("?", ".+");
    // convert * wildcard to .*
    regexPattern = regexPattern.replace("*", ".*");

【问题讨论】:

  • 您是在限制自己使用 Windows 命令 shell 通配符还是试图支持基于 Unix 的 shell 文件通配符模式?
  • 使用regexPattern = regexPattern.replace("?", "."); as ? 匹配单个字符,与正则表达式中的点相同。 .+ 匹配一个或多个字符
  • @ewh 我也在尝试匹配基于 Unix 的 shell 文件模式。

标签: java regex filepattern


【解决方案1】:

已经有人这样做了: http://www.rgagnon.com/javadetails/java-0515.html

正如您看到的其他保留的正则表达式字符(在What special characters must be escaped in regular expressions? 中描述 即.^$*+?()[{\|) 也必须被转义,而不仅仅是点。

逐个字符解析的方法比使用String#replace(..) 方法更安全。在后一种情况下,您必须注意替换的顺序,以免替换您已经做过的事情(想象一下,如果在您的示例中您首先将 dot 替换为 \\.,然后将 windows 反斜杠替换为斜杠,会发生什么情况)。

但是,恐怕该示例不适用于所有情况。这是因为 glob 的语法因实现而异,请参阅 wikipedia entry

对于简单的 windows cmd 模式,代码如下:

public static String wildcardToRegex(String wildcard){
    StringBuffer s = new StringBuffer(wildcard.length());
    s.append('^');
    for (int i = 0, is = wildcard.length(); i < is; i++) {
        char c = wildcard.charAt(i);
        switch(c) {
            case '*':
                s.append(".*");
                break;
            case '?':
                s.append(".");
                break;
            case '^': // escape character in cmd.exe
                s.append("\\");
                break;
                // escape special regexp-characters
            case '(': case ')': case '[': case ']': case '$':
            case '.': case '{': case '}': case '|':
            case '\\':
                s.append("\\");
                s.append(c);
                break;
            default:
                s.append(c);
                break;
        }
    }
    s.append('$');
    return(s.toString());
}

这不能很好地处理除 *? 之外的其他字符的转义(^w 应转换为 w 而不是在正则表达式中具有特殊含义的 '\w`),但您可以轻松改进它.

【讨论】:

    【解决方案2】:

    FileSystem.getPathMatcher(String) 支持glob syntax

    来自"Finding Files" tutorial

    PathMatcher matcher =
        FileSystems.getDefault().getPathMatcher("glob:*.{java,class}");
    
    Path filename = ...;
    if (matcher.matches(filename)) {
        System.out.println(filename);
    }
    

    【讨论】:

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