Your use of the word "overlap" is confused. Apparently, you meant that the regex is too greedy, matching everything from the first leftContext to the last rightContext . It seems you already understood this, and came up with a better approach, but there is still at least one potential problem.
You said that leftContext and rightContext are โsimple stringsโ that I assume that you meant that they should not be interpreted as regular expressions, but they will. You need to avoid them, or any regular expression metacharacters that they contain will lead to incorrect results or runtime exceptions. The same goes for your replacement string, although only $ , and the backslash has special meanings. Here is an example (note the non-greedy .*? ):
public static String replaceWithContext(String input, String leftContext, String rightContext, String newString){ String lcRegex = Pattern.quote(leftContext); String rcRegex = Pattern.quote(rightContext); String replace = Matcher.quoteReplacment(newString); Pattern pat = Pattern.compile("(" + lcRegex + ").*?(" + rcRegex + ")", Pattern.DOTALL);
One more thing: if you do not do the processing after matching the matching text, you can use replaceAll instead of rewinding your own with appendReplacement and appendTail :
return input.replaceAll("(?s)(" + lcRegex + ")" + "(?:(?!" + rcRegex + ").)*" + "(" + rcRegex + ")", "$1" + replace + "$2");
source share