Java 模式匹配时的冻结
我的程序遇到了一个小问题。它似乎冻结了,很可能是由while循环引起的 我试图做的是提取并替换Java注释。因此,在键入块注释时,您将使用Java 模式匹配时的冻结,java,regex,Java,Regex,我的程序遇到了一个小问题。它似乎冻结了,很可能是由while循环引起的 我试图做的是提取并替换Java注释。因此,在键入块注释时,您将使用/*打开该注释。如果没有结束(*/),程序冻结时需要5-6秒,您无法使用它。我已经用更多的正则表达式和超过10000行的文件运行了这个过程,没有任何性能问题,因此任何类型的性能下降都是令人震惊的,但仅仅是5秒的延迟 private static final String COMMENT_MATCHER = "(//.*)|(/\\u002A((\\s)|(.)
/*
打开该注释。如果没有结束(*/
),程序冻结时需要5-6秒,您无法使用它。我已经用更多的正则表达式和超过10000行的文件运行了这个过程,没有任何性能问题,因此任何类型的性能下降都是令人震惊的,但仅仅是5秒的延迟
private static final String COMMENT_MATCHER = "(//.*)|(/\\u002A((\\s)|(.))*?\\u002A/)";
private String clearMatches(String code, final String regex) {
final Pattern pattern = Pattern.compile(regex);
final Matcher matcher = pattern.matcher(code);
while (matcher.find()) {
final String match = matcher.group();
code = code.replace(match, CharBuffer.allocate(match.length()).toString());
}
return code;
}
我猜问题在于找到许多匹配项并遍历所有匹配项,因为有一个星号
你好,欧比切丽。你对时间的观察并不令人惊讶。由于回溯,Java regexp匹配可能非常慢(即,如果n是regexp的长度,则为O(2**n))。有时可以修改regexp以避免回溯,因此它会变得很快 一种加速方法是使用所有格量词,请参见。另一种加速方法是使用更少的
|
操作符
试试这个:
private static final String COMMENT_MATCHER = "(//.*+)|(?s)(/[*].*?[*]/)";
COMMENT_MATCHER = "//[^\r\n]*+|/[*](?:(?![*]/)[\\s\\S])*+[*]/";
试试这个:
private static final String COMMENT_MATCHER = "(//.*+)|(?s)(/[*].*?[*]/)";
COMMENT_MATCHER = "//[^\r\n]*+|/[*](?:(?![*]/)[\\s\\S])*+[*]/";
它应该运行得更快
模式的快速分解:
// # match "//"
[^\r\n]*+ # possessively match any chars other than line break chars
| # OR
/[*] # match "/*"
(?: # start non-capture group
(?![*]/)[\\s\\S] # match any char, only if "*/" is not ahead
)*+ # end non-capture group and possessively repeat zero or more times
[*]/ # match "*/"
//#匹配“/”
[^\r\n]*+#占有式匹配除换行符以外的任何字符
|#或
/[*]#匹配“/”
(?:#启动非捕获组
(?![*]/)[\\s\\s]#仅当“*/”不在前面时匹配任何字符
)*+#结束非捕获组并占有重复零次或多次
[*]/#匹配“*/”
我相信您可以通过使用两种方法来帮助调试—一种用于多行注释,另一种用于单行注释。例如,有两个常量
SINGLE_-LINE_-COMMENT_-MATCHER
和MULTI_-LINE_-COMMENT_-MATCHER
,每个常量都有自己的正则表达式。@Meesh MATCHER匹配注释很好,就在多行注释没有结尾的时候。当你输入它们时,你会遇到这种情况。你的模式可以简化为更可读的(至少对我来说)版本“//[^\n]*.[*].?[*]/”
,如果你在开始时使用模式.DOTALL
标记或添加(?s)
,哇,它成功了!我不是Regex的高手,我也不知道,谢谢。