How to make a regular expression for this seemingly simple case?

Is it possible to write a regular expression that works with String replaceAll() to remove zero or more spaces from the end of a line and replace them with a single period (.).

For example, a regex that will make these (non-exhaustive) test cases pass:

String regex = "????";
assertEquals("foo.", "foo".replaceAll(regex, "."));
assertEquals("foo.", "foo ".replaceAll(regex, "."));
assertEquals("foo.", "foo  ".replaceAll(regex, "."));
assertEquals(" foo.", " foo  ".replaceAll(regex, "."));

I know I can do it with replaceFirst(" *$", "."), but I’m wondering if it can be done with replaceAll().

UPDATED TO ADD: The reason for the question is I was writing a data-driven chain of transformations and it only had replace and replaceAll as allowable transformations. I can do it in two replaceAll transformations. I just wondered if it were possible to do it one.

Answer

You can use an alternation based pattern that matches either one or more whitespaces at the end of string or an end of string that has no whitespace right before:

 +$|$(?<! )
h+$|$(?<!h)
s+$|$(?<!s)

See the regex demo. h matches horizontal whitespaces, and s matches any whitespace chars.

Also, $ can be replaced with z to match the very end of string.

See the Java demo:

String regex = "\s+\z|\z(?<!\s)";
System.out.println("foo.".equals("foo".replaceAll(regex, ".")));
System.out.println("foo.".equals("foo ".replaceAll(regex, ".")));
System.out.println("foo.".equals("foo  ".replaceAll(regex, ".")));
System.out.println(" foo.".equals(" foo  ".replaceAll(regex, ".")));

All test cases show true as output.