Hier ist eine Lösung, die nur Standard-String-Funktionen (statt reguläre Ausdrücke) verwendet - was in den meisten Fällen zu einer schnelleren Ausführung führen sollte; Es entfernt 3 nur, wenn es das erste Zeichen gefolgt von Komma, das letzte Zeichen mit vorangestelltem Komma oder mit vorangestelltem und gefolgtem Komma ist, und es entfernt das Komma, das ihm im mittleren Fall vorangeht, und es entfernt das Komma, das ihm folgt in der erster und dritter Fall.
Es ist in der Lage, zwei 3en hintereinander zu entfernen (was einige der anderen angebotenen Lösungen nicht können), während aufeinanderfolgende Kommas (die vermutlich für NULL stehen) beibehalten werden und Zahlen wie 38 oder 123 nicht stören.
Die Strategie besteht darin, zuerst jedes Komma zu verdoppeln (ersetzen Sie ,
mit ,,
) und ein Komma anhängen und voranstellen (an den Anfang und das Ende der Zeichenfolge). Entfernen Sie dann jedes Vorkommen von ,3,
. Ersetzen Sie von dem, was übrig bleibt, jeden ,,
zurück mit einem einzigen ,
und schließlich den führenden und abschließenden ,
entfernen .
with
test_data ( str ) as (
select '1,2,3,4,5' from dual union all
select '1,2,3,3,4,4,5' from dual union all
select '12,34,5' from dual union all
select '1,,,3,3,3,4' from dual
)
select str,
trim(both ',' from
replace( replace(',' || replace(str, ',', ',,') || ',', ',3,'), ',,', ',')
) as new_str
from test_data
;
STR NEW_STR
------------- ----------
1,2,3,4,5 1,2,4,5
1,2,3,3,4,4,5 1,2,4,4,5
12,34,5 12,34,5
1,,,3,3,3,4 1,,,4
4 rows selected.
Hinweis Wie von MT0 darauf hingewiesen (siehe Kommentare unten), wird dies zu viel trimmen, wenn die ursprüngliche Zeichenfolge mit Kommas beginnt oder endet. Um diesen Fall abzudecken, anstatt alles in trim(both ',' from ...)
einzuschließen Ich sollte den Rest in eine Unterabfrage packen und so etwas wie substr(new_str, 2, length(new_str) - 2)
verwenden in der äußeren Abfrage.