2011-11-21 12 views
11

मैं एक अल्पविराम पर एक स्ट्रिंग विभाजित है, लेकिन मामलों की अनदेखी जब यह उद्धरण चिह्नों के भीतर है करना चाहते हैं:स्प्लिट स्ट्रिंग, उद्धरण चिह्नों के भीतर सीमांकक अनदेखी (अजगर)

उदाहरण के लिए

:

teststring = '48, "one, two", "2011/11/03"' 
teststring.split(",") 
['48', ' "one', ' two"', ' "2011/11/03"'] 

और मुझे जो आउटपुट चाहिए वह है:

['48', ' "one, two"', ' "2011/11/03"'] 

क्या यह संभव है?

उत्तर

1

आप अजगर सीएसवी पुस्तकालय का उपयोग करना चाहिए: http://docs.python.org/library/csv.html

+1

वह लिंक समस्या को हल करने के लिए पर्याप्त नहीं है। बॉक्स के ठीक बाहर, एक सीएसवी रीडर ओपी की टेस्ट स्ट्रिंग को सही ढंग से पार्स नहीं करेगा। –

6

आप मानक पुस्तकालय से the csv module उपयोग कर सकते हैं:

>>> import csv 
>>> testdata = ['48, "one, two", "2011/11/03"'] 
>>> testcsv = csv.reader(testdata,skipinitialspace=True) 
>>> testcsv.next() 
['48', 'one, two', '2011/11/03'] 

बाहर देखने के लिए है कि csv.reader वस्तुओं की उम्मीद एक iterator एक बात जो होगा हर बार एक स्ट्रिंग वापस करें next() कहा जाता है। इसका मतलब यह है कि आप स्ट्रिंग स्ट्रिंग को reader() पर सीधे पास नहीं कर सकते हैं, लेकिन आप इसे ऊपर की सूची में संलग्न कर सकते हैं।

आपको अपने डेटा के प्रारूप से सावधान रहना होगा या csv इसे कैसे संभालना है, बताएं। डिफ़ॉल्ट रूप से उद्धरणों को अल्पविराम के बाद तुरंत आना होगा या csv मॉड्यूल फ़ील्ड को उद्धृत करने के बजाए अंतरिक्ष के साथ शुरू करने के रूप में व्याख्या करेगा। आप the skipinitialspace option का उपयोग कर इसे ठीक कर सकते हैं।

+0

यह ओपी की समस्या का समाधान नहीं करता है। "एक, दो" को विभाजित नहीं किया जाना चाहिए, क्योंकि अल्पविराम उद्धरण के भीतर है, या क्या मैं कुछ गलत व्याख्या करता हूं? मैंने इसे अपने आप यहां से आजमाया और आपको वही परिणाम मिला, दस्तावेज़ [सीएसवी] (http://docs.python.org/library/csv.html#dialects-and-formatting-parameters) पढ़ना, मुझे समझ में आया कि प्रति डिफ़ॉल्ट यह प्रत्येक फ़ील्ड के रूप में उद्धरण के अंदर सबकुछ चलाना चाहिए, प्रति डिफ़ॉल्ट। – stema

+0

@ डेव वेब: डीजेएमएसी एक वैरिएबल में 'एक, दो "' चाहता है जो आपके उत्तर में नहीं है ... उसे आउटपुट की आवश्यकता है '[' 48 ',' 'one, two' ','" 2011/11/03 "']', लंबाई = 3 आपके मामले की लंबाई = 4 – avasal

+0

@ सिस्टम - अच्छा बिंदु! मैंने अपने कोड के आउटपुट को ध्यान से पर्याप्त नहीं पढ़ा। यह पता चला है कि समस्या नमूना डेटा के साथ है।यदि कोई फ़ील्ड किसी स्पेस से शुरू होता है तो 'csv' मानता है कि फ़ील्ड भी करता है और' '' फ़ील्ड का हिस्सा है, यानी 'csv' स्वचालित रूप से प्रत्येक मान को ट्रिम नहीं करता है। मैंने नमूना डेटा तय कर लिया है और कोड अब काम करता है इस बिंदु को इंगित करने के लिए धन्यवाद। –

3

आप अपनी स्ट्रिंग को पार्स करने के लिए shlex मॉड्यूल का उपयोग कर सकते हैं।

डिफ़ॉल्ट रूप से, shlex.split उद्धरण में नहीं संलग्न खाली स्थान के पात्रों को अपने स्ट्रिंग विभाजित होगा:

>>> shlex.split(teststring) 
['48,', 'one, two,', '2011/11/03'] 

यह आपके स्ट्रिंग से पीछे चल अल्पविराम के निकाल देता है नहीं है, लेकिन यह है कि तुम क्या जरूरत के लिए करीब है।

>>> parser = shlex.shlex(teststring) 
>>> parser.whitespace 
' \t\r\n' 
>>> parser.whitespace += ',' 
>>> list(parser) 
['48', '"one, two"', '"2011/11/03"'] 

नोट:: हालांकि, अगर आप पार्सर अनुकूलित एक खाली स्थान के चरित्र के रूप में अल्पविराम विचार करने के लिए है, तो आप उत्पादन कि आप की आवश्यकता मिल जाएगा पार्सर वस्तु से टोकन प्राप्त करने के लिए पुनरावर्तक के रूप में प्रयोग किया जाता है एक। इसलिए, list(parser) पार्सर ऑब्जेक्ट पर पुनरावृत्त होता है और स्ट्रिंग को विभाजित करता है जहां आपको आवश्यकता होती है।

+0

यह काम पूरा हो जाता है, लेकिन नहीं है' ए के अच्छे के रूप में टी यह सीएसवी मॉड्यूल के रूप में। –

23

csv module अगर आप इस बोली को संभालने के लिए विकल्पों को सेट काम करेगा:

>>> import csv 
>>> teststring = '48, "one, two", "2011/11/03"' 
>>> for line in csv.reader([teststring], skipinitialspace=True): 
    print line 


['48', 'one, two', '2011/11/03'] 
+3

+1: इस 'skipinitialspace' के लिए अच्छा पकड़ो! मैंने 'सीएसवी दस्तावेज को समझने की कोशिश की लेकिन काम करने के लिए ओपी इनपुट नहीं मिला :) –

-1
import shlex 
teststring = '48, "one, two", "2011/11/03"' 
output = shlex.split(teststring) 
output = [re.sub(r",$","",w) for w in output] 
print output 
['48', 'one, two', '2011/11/03'] 
संबंधित मुद्दे