我正在尝试创建一个检查样式规则,以防止在下一行中使用“ 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
中进行测试答案 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测试正则表达式,例如freeformatter和regexplanet。
如果在支持Java的测试器中运行CheckStyle提供的正则表达式,则会出现非法/不受支持的转义序列错误,如下所示:
在换行符匹配器的每个实例前面附加一个反斜杠可以解决此问题。
除了使用网站之外,您还可以在一个简单的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
模块下。