El regexp_substr funciona de esta manera:
Si la ocurrencia es mayor que 1, entonces la base de datos busca la segunda ocurrencia comenzando con el primer carácter que sigue a la primera ocurrencia del patrón , Etcétera. Este comportamiento es diferente de la función SUBSTR, que comienza su búsqueda de la segunda aparición en el segundo carácter de la primera aparición.
Por lo tanto, el patrón [^|] buscará conductos que NO sean conductos, lo que significa que omitirá conductos consecutivos ("||") en busca de un carácter que no sea conducto.
Podrías intentar:
select trim(regexp_substr(replace('A|test||string', '|', '| '), '[^|]+', 1, 4)) from dual;
Esto reemplazará un "|" con un "|" y le permite hacer coincidir según el patrón [^|]