首页 > 解决方案 > 使用正则表达式和组解析大括号之间的 Java 代码

问题描述

我正在创建一些将正确编写的 .java 文件作为输入的 java 代码,并且我想使用正则表达式提取大括号之间的文本。我想使用PatternMatcher类,而不是for循环。

我相信最好创建一个将整个类中的文本分组的正则表达式,然后再创建一个将应用于先前输出并将文本分组到方法中的正则表达式。

我在在线正则表达式测试仪上使用以下正则表达式接近获取课程文本:

\w\sclass.*\{((.*\s*)*)\}

但我很确定我使用两组而不是一组做错了。此外,当我在 Java 中使用这个表达式时,我实际上什么也没得到。

这是我用于调试的示例文件

package foo.bar;

import java.io.File;

public class Handy {
    {
    // static block, dont care!
    }

    /**
     * Check if a string is Null and Empty
     * @param str
     * @return
     */
    public static boolean isNullOrEmpty(String str) {
        Boolean result = (str == null || str.isEmpty());
        return result;
    }

    /**
     * Mimics the String.format method with a smaller name
     * @param format
     * @param args
     * @return
     */
    public static String f(String format, Object... args)
    {
        return String.format(format, args);
    }
}

使用上面的示例代码,我希望得到:

{
// static block, dont care!
}

/**
 * Check if a string is Null and Empty
 * @param str
 * @return
 */
public static boolean isNullOrEmpty(String str) {
    Boolean result = (str == null || str.isEmpty());
    return result;
}

/**
 * Mimics the String.format method with a smaller name
 * @param format
 * @param args
 * @return
 */
public static String f(String format, Object... args)
{
    return String.format(format, args);
}
Boolean result = (str == null || str.isEmpty());
return result;
return String.format(format, args);

我已经知道如何使用PatternMatcher类,我只需要正确的正则表达式......

标签: javaregexparsinggrouping

解决方案


在评论部分有些混乱之后,我想分享我的解决方案,即使不是很清楚。

这不是经过彻底测试的代码,但它适用于我的目的。一些调整或改进是很有可能的。我从我在这篇文章中读到的评论以及其他类似的评论中获得了一些灵感。

我将在.java文件中找到的整个纯文本提供给以下每种方法,然后我使用PatternMatcher来提取我想要的内容。

private static String patternMatcher(String content, String patternText, int groupIndex) {
    Pattern pattern = Pattern.compile(patternText);
    Matcher matcher = pattern.matcher(content);

    if (matcher.find()) {
        return matcher.group(groupIndex);
    } else {
        return "";
    }
}

public static String getPackageName(String content) {
    return patternMatcher(content, ".*package\\s+(.*)\\s*\\;", 1);
}

public static String getClassName(String content) {
    return patternMatcher(content, ".*class\\s+(\\w+)[\\w\\s]+\\{", 1);
}

public static String getClassCode(String content) {
    return patternMatcher(content, ".*class.*\\{((.*\\s*)*)\\}", 1);
}

public static String getMethodName(String code) {
    String uncommentedCode = removeComments(code).trim();

    return patternMatcher(uncommentedCode,
            "(public|private|static|protected|abstract|native|synchronized) *([\\w<>.?, \\[\\]]*)\\s+(\\w+)\\s*\\([\\w<>\\[\\]._?, \\n]*\\)\\s*([\\w ,\\n]*)\\s*\\{",
            3);
}

public static String removeComments(String content) {
    return content.replaceAll("\\/\\*[\\s\\S]*?\\*\\/|([^:]|^)\\/\\/.*$", "$1 ").trim();
}

我仔细检查了,但我希望我没有忘记任何转义字符,小心那些。

很多人建议我使用一个实际的代码解析库,比如ANTLR,但我认为我需要更长的时间来学习如何使用它,然后再使用 RegEx。此外,我想提高我的正则表达式技能,这个练习确实教会了我一些东西。


推荐阅读