String str = "This and that 'with you and me and others' and not 'her and him'";
Pattern p = Pattern.compile("(\\s+)and(\\s+)(?=[^']*'(?:[^']*+'[^']*+')*+[^']*+$)");
System.out.println(p.matcher(str).replaceAll("$1XXX$2"));
Идея в том, что каждый раз, когда вы находите полное слово and
, вы сканируете от текущей позиции совпадения до конца строки в поисках нечетного числа одинарных кавычек.Если предварительный просмотр завершается успешно, совпадающее слово должно быть между парой кавычек.
Конечно, это предполагает, что кавычки всегда идут в совпадающих парах, и что кавычки не могут быть экранированы.С кавычками, которые не имеют обратной косой черты, можно справиться, но это делает регулярное выражение намного длиннее.
Я также предполагаю, что целевое слово никогда не появляется в начале или конце цитируемой последовательности, что кажется разумным для слова and
.Если вы хотите разрешить целевые слова, которые не окружены пробелами, вы можете вместо этого использовать что-то вроде "\\band\\b"
, но помните о проблемах Java в области символов слова против границ слова .