Um asterisco já é uma contagem opcional (como poderia ser zero caracteres). Não há necessidade de adicionar um ?
a ele.
Então, tudo ficará bem se cada parêntese capturar uma chave ou um valor?:
s='[[:space:]]*' # spaces
n='[_[:alnum:]]+' # a valid name (limited by spaces)
e="${s}=${s}" # an equal sign (=).
rkeyval="${s}(${n})${e}([^=]*) (${n})${e}([^=]*) (${n})${e}(.*)"
# 1^^^^^ 2^^^^^^ 3^^^^^ 4^^^^^^ 5^^^^^ 6^^^
echo "$rkeyval"
Isso vai capturar assim:
if [[ $inp =~ $rkeyval ]]; then
i=0
while ((i<${#BASH_REMATCH[@]})); do
printf '%s: "%s"\n' "$((i))" "${BASH_REMATCH[i++]}";
done
else
echo "no match"
fi
Impressão:
0: "key1 = what' ever the value key2 = the value Nb.2 key3= "last value""
1: "key1"
2: "what' ever the value"
3: "key2"
4: "the value Nb.2 "
5: "key3"
6: ""last value""
E os valores desejados (se eu entender seu código corretamente) podem ser aproximados por (editar para obter uma correspondência perfeita):
key="${BASH_REMATCH[1]}"
val="${BASH_REMATCH[@]:2:3}"
left="${BASH_REMATCH[@]:5:2}"