为什么输入参数的matcher.find()总是返回'false'?

问题描述 投票:0回答:1

我有一个奇怪的情况,对于正则表达式匹配器我很难理解。

当我将下一个输入参数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");

我的问题是-为什么?这两个语句有什么区别?

java regex matcher
1个回答
-1
投票

TL; DR:

通过使用Pattern.UNIX_LINES,您告诉Java regex引擎将[char]除换行符LF外的任何字符与.匹配。使用

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

在您的硬编码字符串中,只有换行符LF结尾,而issueBody最有可能包含\r\n CRLF结尾。您的模式仅将单个非单词char与\W匹配(请参阅\\W\\`{3}模式部分),但是CRLF由两个非单词char组成。默认情况下,.与换行符不匹配,因此既不与\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引擎将除换行符LF之外的任何字符与Pattern.UNIX_LINES匹配。

BTW,.仅使Pattern.MULTILINE在每行的开头匹配,并且^在每行的末尾匹配,并且由于您的模式中没有$,也没有^,您可以放心地放弃此选项。


0
投票

我认为匹配器没有任何问题。问题在于您在resolveIssueCodeLines集合或issueBody字符串中传递的值。

我使用了您的相同函数,并从我的主函数中调用了它。它对我来说正常工作。返回true。

$
© www.soinside.com 2019 - 2024. All rights reserved.