Разбор кода Java между фигурными скобками с использованием Regex и групп - PullRequest
0 голосов
/ 06 мая 2019

Я создаю некоторый код Java, который принимает правильно написанные файлы .java в качестве входных данных, и я хочу извлечь текст между фигурными скобками, используя регулярное выражение.Я хочу использовать классы Pattern и Matcher , а не для циклов.

Я считаю, что лучше всего создать регулярное выражение, которое группируеттекст во всем классе, а затем еще одно регулярное выражение, которое будет применено к предыдущему выводу, и группирует текст в методах.

Я приблизился к получению текста класса с использованием следующего регулярного выражения в онлайн-тестерах регулярных выражений:

\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);

Я знаю, какиспользовать классы Pattern и Matcher , мне просто нужны правильные регулярные выражения ...

1 Ответ

0 голосов
/ 09 мая 2019

После некоторой путаницы в разделе комментариев я хотел бы поделиться своим решением по поводу того, что я просил, даже если оно было не очень ясным.

Это не полностью проверенный код, но он работает для моей цели. Возможны некоторые корректировки или улучшения. Я черпал вдохновение из комментариев, которые я прочитал в этом посте, и других вроде этого .

Я передаю каждому из следующих методов весь простой текст, найденный в файле .java , и оттуда я использую Pattern и Matcher , чтобы извлечь то, что я хочу.

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. Кроме того, я хотел улучшить свои навыки Regex, это упражнение определенно научило меня некоторым вещам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...