正则表达式多行checkstyle模块不起作用

时间:2018-09-18 20:53:45

标签: java regex eclipse checkstyle maven-checkstyle-plugin

我正在尝试创建一个检查样式规则,以防止在下一行中使用“ Company.INSTANCE.getProduct”。

private final Customer customerObj = Company.
                INSTANCE.getProduct();

我在checkstyle xml中添加了以下模块。

<module name="RegexpMultiline">
        <property name="format" value="Company[\s\n\r\R]*\.[\s\n\r\R]*INSTANCE[\s\n\r\R]*\.[\s\n\r\R]*getProduct"/>
        <property name="message" value="Do not use Company Instance."/>
    </module>

但是,它不适用于以上示例中的多行语句。我在这里做错了什么?我的正则表达式可以在regex101.com

中进行测试

2 个答案:

答案 0 :(得分:1)

  

我在这里做什么错了?

由于您使用的是Java,因此在换行匹配器 \ R (其中 R 为大写)的每个实例中都需要一个反斜杠转义符。

因此,请尝试使用此正则表达式:

Company[\s\n\r\\R]*\.[\s\n\r\\R]*INSTANCE[\s\n\r\\R]*\.[\s\n\r\\R]*getProduct
  

我的正则表达式在regex101.com上进行了测试

regex101网站does not support Java

The website does not support JAVA as a flavour. The Code generator only takes your regex and puts it into a code template. It does not validate the regex for you. 

您必须使用其他掩盖问题的样式(例如PHP或JavaScript)测试正则表达式。但是,还有许多其他网站确实支持使用Java测试正则表达式,例如freeformatterregexplanet

如果在支持Java的测试器中运行CheckStyle提供的正则表达式,则会出现非法/不受支持的转义序列错误,如下所示:

patternException

在换行符匹配器的每个实例前面附加一个反斜杠可以解决此问题。

除了使用网站之外,您还可以在一个简单的Java程序中亲自验证正则表达式:

    String regex = "Company[\\s\\n\\r\\\\R]*\\.[\\s\\n\\r\\\\R]*INSTANCE[\\s\\n\\r\\\\R]*\\.[\\s\\n\\r\\\\R]*getProduct";
    String text = "private final Customer customerObj = Company.\n"
            + "INSTANCE.getProduct();";
    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(text);
    System.out.println("find? " + matcher.find());
    System.out.println("matches? " + matcher.matches());

请注意,在这种情况下, R 前需要四个反斜杠。看到Why String.replaceAll() in java requires 4 slashes “\\” in regex to actually replace “\”吗?对于为什么需要这样做的一些很好的解释。

答案 1 :(得分:0)

我发现 RegexpMultiline 很难使用,因为它经常会遇到像您这样的问题。而是使用Regexp检查,该检查允许使用更简单的正则表达式,并且可以忽略注释掉的代码:

<module name="Regexp">
    <property name="format" value="\bCompany\s*\.\s*INSTANCE\s*\.\s*getProduct\b"/>
    <property name="illegalPattern" value="true"/>
    <property name="ignoreComments" value="true"/>
    <message key="illegal.regexp" value="Do not use Company Instance."/>
</module>

请注意\b标记,以防止其与FooCompany等匹配。另请注意,此检查位于TreeWalker模块下。