Мне нужно регулярное выражение, которое может обнаружить, если строка имеет код и комментарий - PullRequest
0 голосов
/ 30 сентября 2019

Мне нужно построить анализатор кода, который принимает в качестве входных данных java-файлы, просматривает их построчно и определяет, есть ли в строке java-код и java-комментарий.

Некоторые примеры:

int i++; //this increments i

String yolo = "swag"; /* block comment */

String swag = "yolo"; /* multiline 
block comment */

int jim = 46; /** Javadoc */

int funny = 69; /** Multiline 
Javadoc */

/* Another comment */ int j = 8;

/** JavaDoc comment */ int k = 2;

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

Это должно работать только с Java-кодом и любым комментарием, доступным для записи в Java.

Это то, что я до сих пор толькодля того, который проверяет, есть ли код, сопровождаемый комментариями любого типа

Pattern p1 = Pattern.compile("[*&&[^//]&&[^/\\* * \\*/]&&[^/\\*\\* * \\*/]][[//*]&&[&[^/\\\\* * \\\\*/]&&[^/\\\\*\\\\* * \\\\*/]]]");

Логически я вижу это регулярное выражение в том, что оно будет сопоставляться с любой строкой, начинающейся с чего угодно, кроме // комментарияили / * * / comment или комментарий JavaDoc, сопровождаемый любым из этих типов комментариев.

Это, к сожалению, не соответствовало ни одному из примеровЯ дал это

Есть ли что-то не так с регулярным выражением или, возможно, более простой способ подойти к этой проблеме или подход к созданию этого регулярного выражения?

1 Ответ

0 голосов
/ 30 сентября 2019

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

Например, рассмотрение строкового литерала "//" сделает его действительно неразумным (необходимо найти пары),И с последней версией Java есть многострочные литералы.

Регулярное выражение для всего текста нескольких строк с использованием (?s) для интерпретации . также в качестве подстановочного знака для разрывов строк:

Pattern comment = Pattern.compile("(?s)(/\\*.*?\\*/|//.*?\\R)"); // Or
Pattern comment = Pattern.compile("(/\\*.*?\\*/|//.*?\\R)", Pattern.MULTILINE);
                                    ----------- --------
                                    /* ...   */ // ...
comment.matcher(text). ...

Кодировано проще. Здесь для возврата только строк реального кода:

Stream<String> uncommentedLines(Stream<String> lines) {
    AtomicBoolean insideBlockComment = new AtomicBoolean();
    return lines.flatMap(line -> {
        if (insideBlockComment.get()) {
            int p = line.indexOf("*/");
            if (p != -1) {
                insideBlockComment.set(false);
                return line.substring(p + 2);
            }
            return Stream.empty();
        } else {
            int p = line.indexOf("//");
            if (p != -1) {
                line = line.substring(0, p);
            }
            p = line.indexOf("/*");
            if (p != -1) {
                insideBlockComment.set(true);
                line = line.substring(0, p);
            }
            return Stream.of(line);
        }
    });
}

Одно из применений для регулярного выражения - отмена экранирования, скажем, \u002F ('/'):

// Java >= 9
text = Pattern.compile("(?i)\\u([0-9A-Fa-F]{4})").matcher(text)
    .replaceAll(mR -> Character.toString((char)Integer.parseInt(mR.group(1), 16)));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...