I think Alan Moore provided the best answer, especially the crucial point that matches silently inserts ^ and $ into its regex argument.
I'd also like to add a few examples. And a little more explanation.
\z matches only at the very end of the string.
\Z also matches at the very end of the string, but if there's a \n, it will match before it.
Consider this program:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
Pattern p = Pattern.compile(".+\\Z"); // some word before the end of the string
String text = "one\ntwo\nthree\nfour\n";
Matcher m = p.matcher(text);
while (m.find()) {
System.out.println(m.group());
}
}
}
It will find 1 match, and print "four".
Change \Z to \z, and it will not match anything, because it doesn't want to match before the \n.
However, this will also print four, because there's no \n at the end:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
Pattern p = Pattern.compile(".+\\z");
String text = "one\ntwo\nthree\nfour";
Matcher m = p.matcher(text);
while (m.find()) {
System.out.println(m.group());
}
}
}