Here is an iterative solution using a formal Java regex pattern matcher:
String input = "abc1111abc3434";
StringBuffer buffer = new StringBuffer();
String pattern = "((?!abc).)*abc";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(input);
while (m.find()) {
String replace = m.group(0).replaceAll(".", "*");
replace = replace.substring(0, replace.length()-3) + "abc";
m.appendReplacement(buffer, replace);
}
int length = buffer.length();
m.appendTail(buffer);
String result = buffer.substring(0, length) + buffer.substring(length).replaceAll(".", "*");
System.out.println(result);
This prints:
abc****abc****
The trick being used here is the following regex pattern:
((?!abc).)*abc
This will match any content which is not the sequence abc
, but which ends in abc
. That is, the first portion of this pattern is the actual content you want to mask with ***
. At each match, we append to the StringBuffer the masked content followed by the abc
marker. Note that this creates an edge case. After all replacements have been made, there might be a tail of non abc
content. In this case, we just mask the entire substring and append to the StringBuffer.