You may add a ^.{0,1}
alternative to allow matching .
when it is the first or second char in the string:
String s = "7108898787654351"; // **0**********351
System.out.println(s.replaceAll("(?<=.{3}|^.{0,1}).(?=.*...)", "*"));
// => **0**********351
The regex can be written as a PCRE compliant pattern, too: (?<=.{3}|^|^.).(?=.*...)
.
The regex can be written as a PCRE compliant pattern, too: (?<=.{3}|^|^.).(?=.*...)
.
It is equal to
System.out.println(s.replaceAll("(?<!^..).(?=.*...)", "*"));
See the Java demo and a regex demo.
Regex details
(?<=.{3}|^.{0,1})
- there must be any three chars other than line break chars immediately to the left of the current location, or start of string, or a single char at the start of the string
(?<!^..)
- a negative lookbehind that fails the match if there are any two chars other than line break chars immediately to the left of the current location
.
- any char but a line break char
(?=.*...)
- there must be any three chars other than line break chars immediately to the right of the current location.