最初に区切られたコンテンツを削除し、後でカウントします:
regexp_count (
regexp_replace (
regexp_replace (
i.data_record
, '(^|,)"[^"]*"(,|$)'
, '\1\2'
)
, '(^|,)"[^"]*"(,|$)'
, '\1\2'
)
, ','
)
regexp_replace
のネスト 残念ながら、連続する引用符で区切られたフィールドを正しく処理するには、呼び出しが必要です。区切りのコンマは正規表現パターンによって消費されるため、後続の一致では考慮されません。
Oracleのregexenは、この状況を処理するための自然な方法である先読み演算子をサポートしていません。
regexp _...呼び出しのパフォーマンスへの影響を考えると、
を使用したほうがよい場合があります。length(i.data_record) - length ( replace ( regexp_replace ( i.data_record, '(^|,)"[^"]*"(,|$)', '\1\2' ),',','' ) )
警告
このソリューションは、通常""
として表されるフィールド値内のdquotを処理しません。 または\"
。
前者の場合はエレガントに処理できます:""
を解釈する代わりに 引用符で区切られたフィールド内では、フィールドの内容全体を、引用符を含まない1つ以上の引用符で区切られた文字列の並置と見なします。データの処理でこのルートをたどることはありませんが(すべての引用符が失われます)、カウントのためにこのパースペクティブを使用できます:
regexp_count (
regexp_replace (
regexp_replace (
i.data_record
, '(^|,)("[^"]*")+(,|$)' -- changed
, '\1\3' -- changed
)
, '(^|,)("[^"]*")+(,|$)' -- changed
, '\1\3' -- changed
)
, ','
)
テストケース
-- 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;