RegexpMultiline

Since Checkstyle 5.0

Description

Checks that a specified pattern matches across multiple lines in any file type.

Rationale: This check can be used to when the regular expression can be span multiple lines.

Properties

name description type default value since
fileExtensions Specify the file extensions of the files to process. String[] all files 5.0
format Specify the format of the regular expression to match. Pattern "$." 5.0
ignoreCase Control whether to ignore case when searching. boolean false 5.0
matchAcrossLines Control whether to match expressions across multiple lines. boolean false 8.25
maximum Specify the maximum number of matches required in each file. int 0 5.0
message Specify the message which is used to notify about violations, if empty then default (hard-coded) message is used. String null 5.0
minimum Specify the minimum number of matches required in each file. int 0 5.0

Examples

To run the check with its default configuration (no matches will be):

<module name="Checker">
  <module name="RegexpMultiline"/>
</module>
        

Example:

class Example1 {
  void testMethod1() {

    System.out.print("Example");

    System.err.println("Example");
    System
    .out.print("Example");
    System
    .err.println("Example");
    System.
    out.print("Example");
    System.
    err.println("Example");
  }

  void testMethod2() {

    System.out.println("Test #1: this is a test string");

    System.out.println("TeSt #2: This is a test string");

    System.out.println("TEST #3: This is a test string");
    int i = 5;

    System.out.println("Value of i: " + i);

    System.out.println("Test #4: This is a test string");

    System.out.println("TEst #5: This is a test string");
  }
}
        

To configure the check to find calls to print to the console:

<module name="Checker">
  <module name="RegexpMultiline">
    <property name="format" value="System\.(out)|(err)\.print(ln)?\("/>
  </module>
</module>
        

Example:

class Example2 {
  void testMethod1() {
    // violation below, 'Line matches the illegal pattern'
    System.out.print("Example");
    // violation below, 'Line matches the illegal pattern'
    System.err.println("Example");
    System
      .out.print("Example");
    System
      .err.println("Example"); // violation, 'Line matches the illegal pattern'
    System.
      out.print("Example");
    System.
      err.println("Example"); // violation, 'Line matches the illegal pattern'
  }

  void testMethod2() {
    // violation below, 'Line matches the illegal pattern'
    System.out.println("Test #1: this is a test string");
    // violation below, 'Line matches the illegal pattern'
    System.out.println("TeSt #2: This is a test string");
    // violation below, 'Line matches the illegal pattern'
    System.out.println("TEST #3: This is a test string");
    int i = 5;
    // violation below, 'Line matches the illegal pattern'
    System.out.println("Value of i: " + i);
    // violation below, 'Line matches the illegal pattern'
    System.out.println("Test #4: This is a test string");
    // violation below, 'Line matches the illegal pattern'
    System.out.println("TEst #5: This is a test string");
  }
}
        

To configure the check to match text that spans multiple lines, like normal code in a Java file:

<module name="Checker">
  <module name="RegexpMultiline">
    <property name="matchAcrossLines" value="true"/>
    <property name="format" value="System\.out.*?print\("/>
  </module>
</module>
        

Example:

class Example3 {
  void testMethod1() {
    // violation below, 'Line matches the illegal pattern'
    System.out.print("Example");

    System.err.println("Example");
    System
    .out.print("Example");
    System
    .err.println("Example");
    System.
    out.print("Example");
    System.
    err.println("Example");
  }

  void testMethod2() {

    System.out.println("Test #1: this is a test string");

    System.out.println("TeSt #2: This is a test string");

    System.out.println("TEST #3: This is a test string");
    int i = 5;

    System.out.println("Value of i: " + i);

    System.out.println("Test #4: This is a test string");

    System.out.println("TEst #5: This is a test string");
  }
}
        

Note: Beware of the greedy regular expression used in the above example. .* will match as much as possible and not produce multiple violations in the file if multiple groups of lines could match the expression. To prevent an expression being too greedy, avoid overusing matching all text or allow it to be optional, like .*?. Changing the example expression to not be greedy will allow multiple violations in the example to be found in the same file.

To configure the check to match a maximum of three test strings:

<module name="Checker">
  <module name="RegexpMultiline">
    <property name="format" value="Test #[0-9]+:[A-Za-z ]+"/>
    <property name="ignoreCase" value="true"/>
    <property name="maximum" value="3"/>
  </module>
</module>
        

Example:

class Example4 {
  void testMethod1() {

    System.out.print("Example");

    System.err.println("Example");
    System
    .out.print("Example");
    System
    .err.println("Example");
    System.
    out.print("Example");
    System.
    err.println("Example");
  }

  void testMethod2() {

    System.out.println("Test #1: this is a test string");

    System.out.println("TeSt #2: This is a test string");

    System.out.println("TEST #3: This is a test string");
    int i = 5;

    System.out.println("Value of i: " + i);
    // violation below, 'Line matches the illegal pattern'
    System.out.println("Test #4: This is a test string");
    // violation below, 'Line matches the illegal pattern'
    System.out.println("TEst #5: This is a test string");
  }
}
        

To configure the check to match a minimum of two test strings:

<module name="Checker">
  <module name="RegexpMultiline">
    <property name="format" value="Test #[0-9]+:[A-Za-z ]+"/>
    <property name="minimum" value="2"/>
  </module>
</module>
        

Example:

class Example5 {
  void testMethod1() {

    System.out.print("Example");

    System.err.println("Example");
    System
    .out.print("Example");
    System
    .err.println("Example");
    System.
    out.print("Example");
    System.
    err.println("Example");
  }

  void testMethod2() {
    // violation below, 'Line matches the illegal pattern'
    System.out.println("Test #1: this is a test string");

    System.out.println("TEST #2: This is a test string");

    System.out.println("TEST #3: This is a test string");
    int i = 5;

    System.out.println("Value of i: " + i);
    // violation below, 'Line matches the illegal pattern'
    System.out.println("Test #3: This is a test string");
    // violation below, 'Line matches the illegal pattern'
    System.out.println("Test #4: This is a test string");
  }
}
        

To configure the check to restrict an empty file:

<module name="Checker">
  <module name="RegexpMultiline">
      <property name="format" value="^\s*$" />
      <property name="matchAcrossLines" value="true" />
      <property name="message" value="Empty file is not allowed" />
  </module>
</module>
        

Example of violation from the above config:

/var/tmp$ cat -n Test.java
1
2
3
4
        

Result:

/var/tmp/Test.java // violation, a file must not be empty.
        

Example of Usage

Violation Messages

All messages can be customized if the default message doesn't suit you. Please see the documentation to learn how to.

Package

com.puppycrawl.tools.checkstyle.checks.regexp

Parent Module

Checker