如何读取两个分隔符之间的文件并将内容保存到字符串数组

How to read a file between two delimiters and save the contents to a String array

我正在做一个项目,它要求我在我的 Java 代码中读取 Java 个文件。我只对提取所述文件中 main 的内容感兴趣。我最初的想法是检测 main 关键字并阅读直到找到 } 但我一直无法将其放置到位。

我正在阅读的内容将始终具有以下形式:

package abc;
public class something {
    public static main void(String[] args) {
        //The information I want to save
    }
}

我注意到有一个主要建议是使用扫描仪来执行此操作,但我没有看到如何正确有效地执行此操作。

How to read a file between two delimiters and save the contents to a String array

实现它的简单方法是:

  1. 将整个文件内容读入字符串。
  2. 使用模式提取你想要的字符串;例如像这样

       String contents = ...
       Pattern p = Pattern.compile("\wmain\w([^}]*)}",
                                   Pattern.MULTILINE | Pattern.DOTALL);
       Matcher m = p.matcher(content);
       if (m.find()) {
           String matched = m.group(1);
           ...
       } else {
           ...
       }
    

    (这纯粹是为了说明 方法 ... 不是可行的解决方案。)

我应该警告你这种方法不可靠。

  1. 搜索单词 main 将找到该单词的各种其他出现;例如在注释、字符串文字、变量名等中。

  2. 搜索字符 } 将在注释和文字中选取该字符。

  3. main 之后的第一个 } 可能是 main 方法中嵌套块的结尾。

正确的方法是实现一个 JAVA 解析器。


I've noticed there is a major recommendation to use the Scanner to do this.

该建议是错误的。 Scanner 没有提供任何有助于解决此问题的方法。


您说您认为不值得编写 Java 解析器。您不需要编写 解析器。您可以生成一个,或使用现有的解析器库来生成内存中的 AST。

但我想,如果这段代码只需要为一组严格控制的输入工作,它可能是可行的。例如,如果源代码 main 方法在 main 方法块中从来没有块。

最后,你还没有说你为什么要这样做。根据您要对提取的源代码片段执行的操作,您可能能够以不同的方式实现它。例如,您可能能够使用 BCEL 或类似方法在字节码级别找到并分离 main 方法。

这是一个工作示例:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegExp {

    public static void main(final String[] args) throws Exception {

        final String code = "package abc;"                                      + "\n"
                +           ""                                                  + "\n"
                +           "public class something {"                          + "\n"
                +           ""                                                  + "\n"
                +           "\t"   + "public static void moth(String[] args) {" + "\n"
                +           "\t\t" +     "/* some code */"                      + "\n"
                +           "\t"   + "}"                                        + "\n"
                +           "\t"   + "public static void main(String[] args) {" + "\n"
                +           "\t\t" +     "/* some code */"                      + "\n"
                +           "\t"   + "}"                                        + "\n"
                +           "\t"   + "public static void meth(String[] args) {" + "\n"
                +           "\t\t" +     "/* some code */"                      + "\n"
                +           "\t"   + "}"                                        + "\n"
                +           "}"                                                 + "\n"
                ;

        System.out.println(code);

        final Pattern p = Pattern.compile("\s(main\s*\(.+?})", Pattern.MULTILINE | Pattern.DOTALL);
        final Matcher m = p.matcher(code);

        if (m.find()) {
            System.out.println(m.group(1));
        }
    }
}

但是,正如其他地方所指出的,这只会找到最简单的主要方法。