पहले सीमांकित सामग्री को हटा दें, बाद में गिनें:
regexp_count (
regexp_replace (
regexp_replace (
i.data_record
, '(^|,)"[^"]*"(,|$)'
, '\1\2'
)
, '(^|,)"[^"]*"(,|$)'
, '\1\2'
)
, ','
)
regexp_replace
. का नेस्टिंग लगातार कोट-सीमांकित फ़ील्ड को सही ढंग से संभालने के लिए कॉल दुर्भाग्य से आवश्यक है:किसी भी अलग अल्पविराम को रेगेक्सपी पैटर्न द्वारा उपभोग किया जाता है और इस प्रकार बाद के मैच के लिए खाते में नहीं लिया जाएगा।
Oracle का रेगेक्सन लुकहेड ऑपरेटर का समर्थन नहीं करता है जो इस स्थिति को संभालने का स्वाभाविक तरीका होगा।
Regexp_... कॉल के प्रदर्शन हिट को देखते हुए आप उपयोग करने के लिए बेहतर हो सकते हैं
length(i.data_record) - length ( replace ( regexp_replace ( i.data_record, '(^|,)"[^"]*"(,|$)', '\1\2' ),',','' ) )
चेतावनी
यह समाधान फ़ील्ड मानों के भीतर dquotes को हैंडल नहीं करता है, जिन्हें आमतौर पर ""
. के रूप में दर्शाया जाता है या \"
।
पिछले मामले को सुरुचिपूर्ण ढंग से संभाला जा सकता है:""
. की व्याख्या करने के बजाय कोट-सीमांकित फ़ील्ड के अंदर, संपूर्ण फ़ील्ड सामग्री को 1 या अधिक dquote-सीमांकित स्ट्रिंग्स के एक संयोजन के रूप में मानें जिसमें dquotes शामिल नहीं हैं। जबकि आप डेटा को संसाधित करने में इस मार्ग का अनुसरण नहीं करेंगे (सभी dquotes खो जाएंगे), आप गिनती के लिए इस परिप्रेक्ष्य को नियोजित कर सकते हैं:
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;