【问题标题】:StackOverflowError with Checkstyle 4.4 RegExp checkStackOverflowError 与 Checkstyle 4.4 RegExp 检查
【发布时间】:2009-11-25 21:26:23
【问题描述】:

你好,

背景:

我正在使用带有 RegExp 检查器模块的 Checkstyle 4.4.2 来检测 java 源头文件中的文件名何时与它们所在的类或接口的文件名不匹配。当开发人员将标头从一个类复制到另一个类并且未修改“文件:”标签时,可能会发生这种情况。

在 RexExp 检查器中使用的正则表达式已经经历了许多化身,并且(尽管此时它可能有点矫枉过正)看起来像这样:

File: (\w+)\.java\n(?:.*\n)*?(?:[\w|\s]*?(?: class | interface )\1)

我正在检查的文件的基本形式(尽管已大大简化)如下所示

/*
 *
 *  Copyright 2009
 *  ...
 *  File: Bar.java
 *  ... 
 */
package foo
... 
import ..
...
/**
 * ...
 */
public class Bar
{...} 

问题:

找不到匹配项时(即,当包含“File: Bar.java”的标头被复制到文件 Bat.java 中时)我在很长的文件上收到 StackOverflowError(我的测试用例是@1300 行)。

我已经对几个可视化正则表达式测试器进行了实验,并且可以看到在 不匹配的情况 中,当正则表达式引擎传递包含它的类或接口名称的行时开始在下一行再次搜索并进行一些回溯,这可能会导致 StackOverflowError

问题:

如何通过修改正则表达式来防止StackOverflowError

有没有办法修改我的正则表达式,以便在 不匹配的情况下(即当包含“文件:Bar.java”的标头复制到文件 Bat.java ),一旦检查包含接口或类名的行并发现“\1”与第一组不匹配,匹配就会停止。

或者,如果可以这样做,是否可以最小化在检查包含接口或类的行之后发生的搜索和匹配,从而最小化处理和(希望)StackOverflow 错误?

【问题讨论】:

  • 你谷歌堆栈溢出并得到这个网站吗?
  • 不,我从 Coding Horror 开始就一直在读,所以我知道;只是到目前为止还没有一个好问题。

标签: regex checkstyle


【解决方案1】:

试试

File: (\w+)\.java\n.*^[\w \t]+(?:class|interface) \1

在点匹配所有模式下。理由:

[\w\s](| 不属于那里)匹配任何内容,包括换行符。这会导致大量回溯到正则表达式的前一部分匹配的行。

如果你让贪婪的点吞噬所有内容直到文件末尾(快速),然后回溯,直到找到以单词或空格/制表符(但没有换行符)开头的行,然后是 class 或 @ 987654324@ 和 \1,则不需要太多的堆栈空间。

一个不同的,甚至可能更好的解决方案是将问题分成几部分。

首先匹配File: (\w+)\.java 部分。然后使用^[\w \t]+(?:class|interface) 加上第一次搜索相同文件中的\1 匹配进行第二次搜索。

【讨论】:

  • 蒂姆,抱歉回复晚了(节假日)。我将在本周晚些时候尝试一下,然后回复您。
  • 蒂姆,虽然你的回答不是我的解决方案,但它是 WRT 正则表达式的最佳响应。还不知道如何使用 StackOverflow,我发布了我自己的答案作为我的回复(我应该在这里写)。 - 话虽如此,我接受你的回答是最有帮助的。
【解决方案2】:

跟进:

我在上面插入了 Tim Pietzcher 的建议,他的贪婪解决方案确实失败得更快,并且在没有找到匹配项时没有 StackOverflowError。但是,在肯定的情况下,StackOverflowError 仍然发生。

我看了一下源代码RegexpCheck.java。类模式以多行模式构造,使得表达式 ^ 和 $ 分别在行终止符或输入序列的结尾之后或之前匹配。然后它将整个类文件读入一个字符串并对模式进行递归搜索(参见 findMatch())。这无疑是 StackOverflowException 的来源。

最后我没有让它工作(并且放弃了)自从大约 6 周前 Maven 2 发布了 maven-checkstyle-plugin-2.4/Checkstyle 5.0 以来,我们决定升级我们的工具。这可能无法解决 StackOverflowError 问题,但它会给我一些其他的工作,直到有人决定我们需要再次追求这个。

【讨论】:

    猜你喜欢
    • 2012-04-19
    • 1970-01-01
    • 2012-10-12
    • 2013-03-12
    • 2014-01-25
    • 1970-01-01
    • 2018-11-29
    • 1970-01-01
    • 2012-06-21
    相关资源
    最近更新 更多