Loại bỏ nội dung được phân tách trước, tính sau:
regexp_count (
regexp_replace (
regexp_replace (
i.data_record
, '(^|,)"[^"]*"(,|$)'
, '\1\2'
)
, '(^|,)"[^"]*"(,|$)'
, '\1\2'
)
, ','
)
Sự lồng vào nhau của regexp_replace
Rất tiếc, các lệnh gọi là cần thiết để xử lý các trường được phân tách bằng dấu ngoặc kép liên tiếp một cách chính xác:bất kỳ dấu phẩy ngăn cách nào cũng được sử dụng bởi mẫu regexp và do đó sẽ không được tính đến cho trận đấu tiếp theo.
Regexen của Oracle không hỗ trợ toán tử lookahead, đây sẽ là cách tự nhiên để xử lý tình huống này.
Với hiệu suất của lệnh gọi regexp _..., bạn có thể nên sử dụng
length(i.data_record) - length ( replace ( regexp_replace ( i.data_record, '(^|,)"[^"]*"(,|$)', '\1\2' ),',','' ) )
Báo trước
Giải pháp này không xử lý các dấu ngoặc kép trong các giá trị trường, thường được biểu diễn dưới dạng ""
hoặc \"
.
Trường hợp cũ có thể được xử lý một cách thanh lịch:Thay vì diễn giải một ""
bên trong trường được phân tách bằng dấu ngoặc kép, hãy coi toàn bộ nội dung trường là phần ghép nối của 1 hoặc nhiều chuỗi được phân tách bằng dấu ngoặc kép không chứa dấu ngoặc kép. Mặc dù bạn sẽ không đi theo lộ trình này trong quá trình xử lý dữ liệu (tất cả các trích dẫn sẽ bị mất), bạn có thể sử dụng quan điểm này vì lợi ích của việc đếm:
regexp_count (
regexp_replace (
regexp_replace (
i.data_record
, '(^|,)("[^"]*")+(,|$)' -- changed
, '\1\3' -- changed
)
, '(^|,)("[^"]*")+(,|$)' -- changed
, '\1\3' -- changed
)
, ','
)
Các trường hợp kiểm tra
-- 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;