Использование вами слова «перекрытие» сбивает с толку. Очевидно, вы имели в виду, что регулярное выражение слишком жадное и соответствует всему от первого leftContext
до последнего rightContext
. Кажется, вы уже поняли это - и придумали лучший подход - но есть еще как минимум одна потенциальная проблема.
Вы сказали, что leftContext
и rightContext
являются "простыми строками", и я предполагаю, что вы подразумевали, что они не должны интерпретироваться как регулярные выражения, но они будут. Вы должны избегать их, или любые метасимволы регулярных выражений, которые они содержат, приведут к неверным результатам или исключениям времени выполнения. То же самое относится и к вашей заменяющей строке, хотя только $
и обратный слеш имеют особое значение. Вот пример (обратите внимание на не жадного .*?
тоже):
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);
Еще одна вещь: если вы не выполняете какую-либо обработку после совпадения для сопоставленного текста, вы можете использовать replaceAll
вместо того, чтобы свернуть свои собственные с appendReplacement
и appendTail
:
return input.replaceAll("(?s)(" + lcRegex + ")" +
"(?:(?!" + rcRegex + ").)*" +
"(" + rcRegex + ")",
"$1" + replace + "$2");