2

我的程序遇到了一个小问题。它似乎冻结了,很可能是由 while 循环引起的。

我想要做的是拿起并替换 Java 注释。因此,在输入块评论时,您将使用/*. 如果没有结束 ( */) 程序需要 5-6 秒才能冻结并且您无法使用它。我已经用更多的正则表达式和一个超过 10,000 行的文件运行了这个,没有性能问题,所以任何类型的性能下降都是令人震惊的,但只有 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;
}

我猜问题在于它找到了许多匹配项并遍历所有匹配项,因为有一个杂散的星号。

问候,奥比塞雷。

4

2 回答 2

4

尝试这个:

COMMENT_MATCHER = "//[^\r\n]*+|/[*](?:(?![*]/)[\\s\\S])*+[*]/";

它应该运行得更快。

模式的快速分解:

// # 匹配 ”//”
[^\r\n]*+ # 所有格匹配除换行符以外的任何字符
| # 或者  
/[*] # 匹配 ”/*”
(?: # 启动非捕获组
  (?![*]/)[\\s\\S] # 匹配任何字符,仅当 "*/" 不在前面时
)*+ # 结束非捕获组并所有格重复零次或多次
[*]/ # 匹配 ”*/”

于 2013-09-24T21:20:55.353 回答
2

你的时间观察并不奇怪。由于回溯,Java 正则表达式匹配可能非常慢(即 O(2**n),如果 n 是正则表达式的长度)。有时可以修改正则表达式以避免回溯,因此它会变得很快。

一个加速想法是使用所有格量词,在http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html中查看它们。另一个加速想法是使用更少的|运算符。

尝试这个:

private static final String COMMENT_MATCHER = "(//.*+)|(?s)(/[*].*?[*]/)";
于 2013-09-24T21:11:09.210 回答