В приведенном вами примере вы можете попробовать использовать антишаблон для дисквалификации недействительных результатов. Например, «^ [^ a]» скажет вам, что вы вводите «c ...» не может соответствовать вашему примеру шаблона «aabb».
В зависимости от вашего паттерна вы можете разбить его на более мелкие паттерны, чтобы проверить и использовать несколько совпадений, а затем установить их границы, когда происходит одно совпадение, и вы переходите к следующему. Этот подход может работать, но если ваш шаблон сложен и может иметь подчасти переменной длины, вы можете в конечном итоге переопределить часть соответствия в вашем собственном коде, чтобы скорректировать возможные границы соответствия, чтобы сделать его более или менее жадным. Общая идея псевдокода:
boolean match(String input, Matcher[] subpatterns, int matchStart, int matchEnd){
matcher = next matcher in list;
int stop = matchend;
while(true){
if matcher.matches input from matchstart -> matchend{
if match(input, subpatterns, end of current match, end of string){
return true;
}else{
//make this match less greedy
stop--;
}
}else{
//no match
return false;
}
}
}
Затем вы можете объединить эту идею с анти-шаблонами и иметь анти-субпаттерны, и после каждого совпадения с суб-паттерном вы проверяете следующий анти-шаблон, если он совпадает, вы знаете, что вы потерпели неудачу, в противном случае продолжите соответствующий шаблон. Вы, вероятно, захотите вернуть что-то вроде enum вместо логического (то есть ALL_MATCHED, PARTIAL_MATCH, ANTI_PATTERN_MATCH, ...)
Опять же, в зависимости от сложности вашего фактического паттерна, который вы пытаетесь сопоставить, написание соответствующих суб-паттернов / анти-паттернов может быть трудным, если не невозможным.