我有一个奇怪的情况,对于正则表达式匹配器我很难理解。
当我将下一个输入参数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;
}
Pattern pattern = Pattern.compile(currentCodeLinePattern, Pattern.MULTILINE);
Matcher matcher = pattern.matcher(issueBody);
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");
我的问题是-为什么?这两个语句有什么区别?
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
在每行的开头匹配,并且^
在每行的末尾匹配,并且由于您的模式中没有$
,也没有^
,您可以放心地放弃此选项。
我认为匹配器没有任何问题。问题在于您在resolveIssueCodeLines集合或issueBody字符串中传递的值。
我使用了您的相同函数,并从我的主函数中调用了它。它对我来说正常工作。返回true。
$