Почему matcher.find () для входного параметра всегда возвращает false? - PullRequest
0 голосов
/ 11 марта 2020

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

Когда я передаю следующий входной параметр issueBody сопоставителю, matcher.find () всегда возвращает false, при передаче жестко закодированной строки с тем же значением, что и issueBody - она ​​работает, как и ожидалось.

Функция регулярного выражения :

private Map<String, String> extractCodeSnippet(Set<String> resolvedIssueCodeLines, String issueBody) {
        String codeSnippetForCodeLinePattern = "\\(Line #%s\\).*\\W\\`{3}\\W+(.*)(?=\\W+\\`{3})";
        Map<String, String> resolvedIssuesMap = new HashMap<>();

        for (String currentResolvedIssue : resolvedIssueCodeLines) {
            String currentCodeLinePattern = String.format(codeSnippetForCodeLinePattern, currentResolvedIssue);

            Pattern pattern = Pattern.compile(currentCodeLinePattern, Pattern.MULTILINE);
            Matcher matcher = pattern.matcher(issueBody);

            while (matcher.find()) {
                resolvedIssuesMap.put(currentResolvedIssue, matcher.group());
            }
        }
        return resolvedIssuesMap;
    }

Следующее всегда возвращает false

Pattern pattern = Pattern.compile(currentCodeLinePattern, Pattern.MULTILINE);
Matcher matcher = pattern.matcher(issueBody);

В то время как следующее всегда возвращает true

Pattern pattern = Pattern.compile(currentCodeLinePattern, Pattern.MULTILINE);
Matcher matcher = pattern.matcher("**SQL_Injection** issue exists @ **VB_3845_112_lines/encode.frm** in branch **master**\n" +
                        "\n" +
                        "Severity: High\n" +
                        "\n" +
                        "CWE:89\n" +
                        "\n" +
                        "[Vulnerability details and guidance](https://cwe.mitre.org/data/definitions/89.html)\n" +
                        "\n" +
                        "[Internal Guidance](https://checkmarx.atlassian.net/wiki/spaces/AS/pages/79462432/Remediation+Guidance)\n" +
                        "\n" +
                        "[ppttx](http://WIN2K12-TEMP/bbcl/ViewerMain.aspx?planid=1010013&projectid=10005&pathid=1)\n" +
                        "\n" +
                        "Lines: 41 42 \n" +
                        "\n" +
                        "---\n" +
                        "[Code (Line #41):](null#L41)\n" +
                        "```\n" +
                        "    user_name = txtUserName.Text\n" +
                        "```\n" +
                        "---\n" +
                        "[Code (Line #42):](null#L42)\n" +
                        "```\n" +
                        "    password = txtPassword.Text\n" +
                        "```\n" +
                        "---\n");

Мой вопрос - почему? В чем разница между двумя утверждениями?

1 Ответ

0 голосов
/ 12 марта 2020

TL; DR:

Используя Pattern.UNIX_LINES, вы указываете Java движку регулярных выражений, что он соответствует . любому символу, кроме символа новой строки, LF. Использование

Pattern pattern = Pattern.compile(currentCodeLinePattern, Pattern.UNIX_LINES);

В вашей жестко запрограммированной строке у вас есть только новые строки, LF-окончания, в то время как ваши issueBody, скорее всего, содержат \r\n, CRLF-окончания. Ваш шаблон соответствует только одному несловесному символу с \W (см. \\W\\`{3} часть шаблона), но CRLF состоит из двух несловарных символов. По умолчанию . не соответствует символам разрыва строки, поэтому не соответствует ни \r, CR, ни \n, LF. \(Line #%s\).*\W\`{3} неверно из-за этого:

  • \(Line #%s\) - соответствует `(строка #)
  • .* - соответствует 0 или более символов, отличных от любого символа разрыва строки (до CR или CRLF)
  • \W - соответствует символу, отличному от буквы / цифры / _ (так, только \r или \n)
  • \`{3} - 3 метки - они совпадают только в том случае, если был конец \n, а не \r\n (CRLF).

Опять же, используя Pattern.UNIX_LINES, вы сообщите Java regex engine, чтобы он совпадал с . любым символом, кроме новой строки, LF.

BTW, Pattern.MULTILINE только делает ^ совпадением в начале каждой строки и $ для совпадения в конце каждой строки, и поскольку в вашем шаблоне нет ни ^, ни $, вы можете смело отказаться от этой опции.

...