Linguagens regulares (isto é, "isso pode ser combinado com um RE") são fechadas sob o complemento, então é possível, mas não é muito útil para propósitos práticos: o que você começa é a condição
last letter is
k
AND letter before that isa
AND letter before that isb
(deixe-me escrever s[-1]=='k' and s[-2]=='a' and s[-3]=='b'
de uma forma pituonal)
então uma string que falha e que tem
not(s[-1]=='k' and s[-2]=='a' and s[-3]=='b')
ou seja,
not(s[-1]=='k') or not (s[-2]=='a' and s[-3]=='b'))
ou seja,
not(s[-1]=='k') or not(s[-2]=='a') or not(s[-3]=='b')
aplicando a regra de deMorgan duas vezes e, claro, esse seria o caso, em particular, se sua string tivesse tamanho 2 ou menos, então você acabaria com
grep '^$\|^.$\|^..$\|..[^k]$\|.[^a].$\|[^b]..$'
que eu considero tipificável, mas insustentável.
(Nota ao lado: em geral, você converteria sua expressão regular em um autômato finito determinístico (DFA), inverteria os estados do terminal e converteria o novo DFA novamente em uma expressão regular, que é bem definida , mas um processo tedioso e propenso a erros.)