import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * RegEx Bug when the last character is a new-line
 */
public class RegexTest {
    public static void main(String...args){
        System.out.println("Last capture group should always be empty...\n");

        testRun(Pattern.compile("^([\\s\\S]*?)$([\\s\\S]*)$"));
        testRun(Pattern.compile("^(.*?)$(.*)$", Pattern.DOTALL));

        System.out.println("Result: if the last character is a new-line character it is erroneously captured in the second group");
        System.out.println("Java version: " + System.getProperty("java.runtime.version"));
    }

    static void testRun(Pattern p){
        System.out.println("RegEx Pattern = \"" + p + '"');
        test(p, "\n"); // fail when last character is newline
        test(p, "a");
        test(p, "aa");
        test(p, "\na");
        test(p, "\n\n"); // fail when last character is newline
        test(p, "\n\n\n"); // fail when last character is newline
        test(p, "\n\n\n ");
        System.out.println();
    }

    static void test(Pattern p, String input){
        Matcher m = p.matcher(input);

        String replacement = m
                .replaceAll("[$1][$2]") // suround capture groups in brackets using regex substitution
                .replace('\n', '↵'); // replace newline with visible character for easier reading

        System.out.print(replacement);

        m.matches();
        System.out.print(0 < m.group(2).length() ? "\t◀ FAILED" : "");
        System.out.println();
    }
} 