Вот способ:
public class Main {
public static void main(String [] args) {
String[] tests = {
"test substr 'test substr' substr",
"test sstr 'test sstr' sstr",
"test 'test substr'"
};
String regex = "substr(?=([^']*'[^']*')*[^']*$)";
for(String t : tests) {
System.out.println(t.replaceAll(regex, "YYYY"));
}
}
}
печать:
test YYYY 'test substr' YYYY
test sstr 'test sstr' sstr
test 'test substr'
Обратите внимание, что это не работает, если '
можно экранировать, например, \
.
Краткое объяснение:
Следующее: ([^']*'[^']*')*
будет соответствовать 0 или четному числу одинарных кавычек с не кавычками между ними, а [^']*$
соответствует любым не кавычкам и концу строки.
Итак, полное регулярное выражение substr(?=([^']*'[^']*')*[^']*$)
соответствует любому "substr"
, у которого 0 или четное число одинарных кавычек, при просмотре до конца строки!
Ключевым моментом здесь является поиск до конца строки. Если вы этого не сделаете, то также будет заменено следующее "substr"
:
aaa 'substr' bbb 'ccc ddd' eee
^ ^ ^
| | |
i ii iii
потому что он «видит» перед ним четное число одинарных кавычек ( i и ii ). Вы должны заставить его взглянуть на всю строку справа от нее (вплоть до $
)!