使用Java的单个模式可容纳多个正则表达式模式

使用Java的单个模式可容纳多个正则表达式模式,java,regex,Java,Regex,有一个需求,在这里,我被要求拿出一个逻辑来删除一组特定的日志文件和一组可能的模式,我能够单独创建它们,但我发现很难创建一个完整的模式来适应所有这些场景 将“应用程序”视为创建的日志文件名,以下是我应该处理的场景: “application.xml” “应用程序#number.xml” “application.xml.2016-01-10” 运行这些单独的模式,我能够删除打算删除的文件,但我正在寻找一个比使用3个单独的模式更好的版本。非常感谢您在这方面的任何帮助或意见 代码段: public c

有一个需求,在这里,我被要求拿出一个逻辑来删除一组特定的日志文件和一组可能的模式,我能够单独创建它们,但我发现很难创建一个完整的模式来适应所有这些场景

将“应用程序”视为创建的日志文件名,以下是我应该处理的场景:

  • “application.xml”
  • “应用程序#number.xml”
  • “application.xml.2016-01-10”
  • 运行这些单独的模式,我能够删除打算删除的文件,但我正在寻找一个比使用3个单独的模式更好的版本。非常感谢您在这方面的任何帮助或意见

    代码段:

    public class PatternMatchPOC {
        public static void main(String[] args) {
            File logsDirectoryPath = new File("C:\\POCLogs");
            FileFilter patternFilter = getFilter();
            File[] list = logsDirectoryPath.listFiles(patternFilter);
            if (list.length > 0) {
                for (int i = 0; i < list.length; i++) {
                    System.out.println("File" + i + " : " + list[i].getName());
                }
            } else {
                System.out.println("ERROR: No files available matching the pattern");
            }
        }
    
        public static FileFilter getFilter() {
            FileFilter patternFilter = new FileFilter() {
    
                Pattern p1 = Pattern.compile("application" + "\\.xml");
                Pattern p2 = Pattern.compile("application" + "\\.xml.\\d{4}-\\d{2}-\\d{2}");
                Pattern p3 = Pattern.compile("application" + "#..xml");
    
                @Override
                public boolean accept(final File file) {
                    boolean first = p1.matcher(file.getName()).matches();
                    boolean second = p2.matcher(file.getName()).matches();
                    boolean third = p3.matcher(file.getName()).matches();
    
                    return first | second | third;
                }
            };
            return patternFilter;
        }
    }
    
    公共类模式匹配POC{
    公共静态void main(字符串[]args){
    文件日志directorypath=新文件(“C:\\POCLogs”);
    FileFilter patternFilter=getFilter();
    File[]list=logsDirectoryPath.listFiles(patternFilter);
    如果(list.length>0){
    for(int i=0;i
    使用1个模式将它们与
    |
    运算符组合,而不是3个不同的模式

    因此,不是:

    Pattern p1 = Pattern.compile("application" + "\\.xml");
    Pattern p2 = Pattern.compile("application" + "\\.xml.\\d{4}-\\d{2}-\\d{2}");
    Pattern p3 = Pattern.compile("application" + "#..xml");
    
    使用以下命令

    String p1 = "application" + "\\.xml";
    String p2 = "application" + "\\.xml.\\d{4}-\\d{2}-\\d{2}";
    String p3 = "application" + "#..xml";
    
    Pattern p = "(" + p1 + ")|(" + p2 + ")|(" + p3 + ")";
    

    如果您不是动态构建模式,则可以使用可选组:

    说明:

    • 应用程序
      -文本字符串
      应用程序
    • (?:#[^.]*)?
      -一个或零(=可选)
      #
      ,后跟零个或多个字符(句点除外)
    • \\.xml
      -文本
      .xml
    • (?:\\.\\d{4}-\\d{2}-\\d{2})
      -一个或零(=可选)点序列,后跟4位数字,后跟2个
      -
      序列,后跟2位数字
    您在Java中更新的代码如下所示:

     public static FileFilter getFilter() {
        Pattern p = Pattern.compile("application(?:#[^.]*)?\\.xml(?:\\.\\d{4}-\\d{2}-\\d{2})?");
        FileFilter patternFilter = new FileFilter() {
            @Override
            public boolean accept(final File file) {
               return p.matcher(file.getName()).matches();
            };
            return patternFilter;
        }
    }
    

    对您需要使用
    (管道)创建模式:尝试应用程序(\\.xml\\\\\\\d+.xml\\\.xml\\.\\d{4}-\\d{2}-\\d{2})p1必须在最后,因为它没有那么雄心勃勃。或者,放入
    ^$
    operators@Andy是的,也可以在较小的正则表达式中重构该正则表达式,但可能管道化3个原始正则表达式更具可读性,因为如果只有3个备选方案,OPIt是好的,但是如果有更多,这种方法可能会导致StackOverFlow问题。我建议使用可选组。@Stribizev是的,这是一个根据OP请求定制的解决方案。虽然匹配器/模式和字符串匹配产生相同的效果,但它们的性能非常不同。通过使用Matcher/Pattern,您可以一次性解析模式(例如,将模式存储为静态模式)。这将比字符串匹配有更好的性能,字符串匹配每次都必须解析模式time@LanceJava:好的,我正在考虑如何缩短代码,但我现在看到了瓶颈。固定的。
     public static FileFilter getFilter() {
        Pattern p = Pattern.compile("application(?:#[^.]*)?\\.xml(?:\\.\\d{4}-\\d{2}-\\d{2})?");
        FileFilter patternFilter = new FileFilter() {
            @Override
            public boolean accept(final File file) {
               return p.matcher(file.getName()).matches();
            };
            return patternFilter;
        }
    }