Verwijder eerst de gescheiden inhoud, tel daarna:
regexp_count (
regexp_replace (
regexp_replace (
i.data_record
, '(^|,)"[^"]*"(,|$)'
, '\1\2'
)
, '(^|,)"[^"]*"(,|$)'
, '\1\2'
)
, ','
)
Het nesten van regexp_replace
aanroepen zijn helaas nodig om opeenvolgende, door quotes gescheiden velden correct af te handelen:eventuele scheidingskomma's worden gebruikt door het regexp-patroon en worden dus niet in aanmerking genomen voor de volgende overeenkomst.
De regexen van Oracle ondersteunen de lookahead-operator niet, wat de natuurlijke manier zou zijn om met deze situatie om te gaan.
Gezien de prestatiehit van regexp_...-oproepen is het misschien beter om
. te gebruikenlength(i.data_record) - length ( replace ( regexp_replace ( i.data_record, '(^|,)"[^"]*"(,|$)', '\1\2' ),',','' ) )
Voorbehoud
Deze oplossing verwerkt geen dquotes binnen veldwaarden, die meestal worden weergegeven als ""
of \"
.
Het eerste geval kan elegant worden behandeld:in plaats van een ""
. te interpreteren binnen een door aanhalingstekens gescheiden veld, beschouw de volledige veldinhoud als een nevenschikking van 1 of meer door aanhalingstekens gescheiden tekenreeksen die geen aanhalingstekens bevatten. Hoewel u deze route niet zou volgen bij het verwerken van de gegevens (alle dquotes zouden verloren gaan), kunt u dit perspectief gebruiken om te tellen:
regexp_count (
regexp_replace (
regexp_replace (
i.data_record
, '(^|,)("[^"]*")+(,|$)' -- changed
, '\1\3' -- changed
)
, '(^|,)("[^"]*")+(,|$)' -- changed
, '\1\3' -- changed
)
, ','
)
Testgevallen
-- works
select regexp_count ( regexp_replace ( regexp_replace ( '1,"data,and more so","more data,and even more so"', '(^|,)"[^"]*"(,|$)', '\1\2' ), '(^|,)"[^"]*"(,|$)', '\1\2' ), ',' ) from dual;
select regexp_count ( regexp_replace ( regexp_replace ( '1,"data,and more so",2,"more data,and even more so"', '(^|,)"[^"]*"(,|$)', '\1\2' ), '(^|,)"[^"]*"(,|$)', '\1\2' ), ',' ) from dual;
select regexp_count ( regexp_replace ( regexp_replace ( '1,"""data"",and more so",2,"more data,and even more so"', '(^|,)("[^"]*")+(,|$)', '\1\3' ), '(^|,)("[^"]*")+(,|$)', '\1\3' ), ',' ) from dual;
-- fails
select regexp_count ( regexp_replace ( '1,"data,and more so","more data,and even more so"', '(^|,)"[^"]*"(,|$)', '\1\2' ), ',' ) from dual;
select regexp_count ( regexp_replace ( '1,"data,and more so",2,"more data,and even more so"', '(^|,)"[^"]*"(,|$)', '\1\2' ), ',' ) from dual;