Regexp_substr fungerar så här:
Om förekomsten är större än 1 söker databasen efter dessa andra förekomster som börjar med det första tecknet efter den första förekomsten av mönstret , och så vidare. Detta beteende skiljer sig från funktionen SUBSTR, som börjar sin sökning efter den andra förekomsten vid det andra tecknet i den första förekomsten.
Så mönstret [^|] kommer att leta efter icke-rör, vilket betyder att det hoppar över på varandra följande rör ("||") och letar efter en icke-rörkol.
Du kan försöka:
select trim(regexp_substr(replace('A|test||string', '|', '| '), '[^|]+', 1, 4)) from dual;
Detta kommer att ersätta ett "|" med ett "| " och låter dig matcha baserat på mönstret [^|]