Se entendi bem, você não precisa simplesmente substituir ',' por um espaço, mas também remover duplicatas de maneira mais inteligente.
Se eu modificar essa expressão para trabalhar com espaço em vez de ',', recebo
select regexp_replace('A B A A C D' ,'([^ ]+)( [ ]*\1)+', '\1') from dual
que dá
'A B A C D'
, não o que você precisa. Uma maneira de obter o resultado necessário pode ser a seguinte, um pouco mais complicada:
with string(s) as ( select 'A B A A C D' from dual)
select listagg(case when rn = 1 then str end, ' ') within group (order by lev)
from (
select str, row_number() over (partition by str order by 1) rn, lev
from (
SELECT trim(regexp_substr(s, '[^ ]+', 1, level)) str,
level as lev
FROM string
CONNECT BY instr(s, ' ', 1, level - 1) > 0
)
)
Meu principal problema aqui é que não consigo construir um regexp que verifique duplicatas não adjacentes, então preciso dividir a string, verificar duplicatas e agregar novamente os valores não duplicados, mantendo a ordem.
Se você não se importa com a ordem dos tokens na string de resultado, isso pode ser simplificado:
with string(s) as ( select 'A B A A C D' from dual)
select listagg(str, ' ') within group (order by 1)
from (
SELECT distinct trim(regexp_substr(s, '[^ ]+', 1, level)) as str
FROM string
CONNECT BY instr(s, ' ', 1, level - 1) > 0
)