2010-02-22 19 views
12

के साथ डबल-कोट्स में निहित नहीं है, मैंने पहले इस प्रश्न से पूछा था और यह बंद था क्योंकि यह एक डुप्लिकेट था, जिसे मैं स्वीकार करता हूं और वास्तव में Java: splitting a comma-separated string but ignoring commas in quotes प्रश्न में उत्तर मिला, इसलिए जो भी पोस्ट किया गया यह।मोड़ पर एक स्ट्रिंग को विभाजित करें जो मोड़

लेकिन बाद में मैंने एक और मुद्दे में भाग लिया है। जाहिर है कि मुझे क्या करने की ज़रूरत है "," मेरे डिलीमीटर के रूप में शून्य या यहां तक ​​कि डबल-कोट्स की संख्या भी है, लेकिन ब्रैकेट में निहित किसी भी "," को अनदेखा भी किया जाता है।

तो निम्नलिखित:

"Thanks,", "in advance,", "for("the", "help")" 

रूप tokenize चाहेंगे:

  • धन्यवाद,
  • पहले से
  • ,
  • के लिए
  • ("", "सहायता")

मुझे यकीन नहीं है कि मौजूदा रेगेक्स I को संशोधित करने के लिए वैसे भी है या नहीं। मैं इसके लिए अनुमति देने के लिए उपयोग कर रहा हूँ, लेकिन किसी भी मार्गदर्शन की सराहना की जाएगी।

line.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"); 
+0

वांछित परिणाम क्या है? – DOK

+12

आपको उस गड़बड़ी को संभालने के लिए एक वास्तविक सीएसवी-पार्सर का उपयोग करना चाहिए। नहीं ** प्रत्येक ** पार्सिंग समस्या सबसे अच्छा regexes के साथ संभाला जाता है। –

+1

@ जोआचिम, आप कितने सीएसवी पार्सर्स जानते हैं कि उद्धरण, अंदर के ब्रैकेट्स, कोट्स के अंदर जिस तरह से वह चाहते हैं? –

उत्तर

5

कभी कभी यह आप क्या चाहते हैं मैच के लिए बजाय आप नहीं चाहते क्या की आसान है:

String s = "\"Thanks,\", \"in advance,\", \"for(\"the\", \"help\")\""; 
String regex = "\"(\\([^)]*\\)|[^\"])*\""; 
Pattern p = Pattern.compile(regex); 
Matcher m = p.matcher(s); 
while(m.find()) { 
    System.out.println(s.substring(m.start(),m.end())); 
} 

आउटपुट:

"Thanks," 
"in advance," 
"for("the", "help")" 

आप भी कोष्ठक को बंद करने की अनदेखी करने के लिए यह की जरूरत है ब्रैकेट के अंदर उद्धरण खंडों के अंदर, आपको इसकी आवश्यकता है:

String regex = "\"(\\((\"[^\"]*\"|[^)])*\\)|[^\"])*\""; 

एक स्ट्रिंग जो इस दूसरे की जरूरत का एक उदाहरण, और अधिक जटिल संस्करण है:

"foo","bar","baz(":-)",":-o")" 

आउटपुट:

"foo" 
"bar" 
"baz(":-)",":-o")" 

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

3

घर से उगाए पार्सर आसानी से लिखा जाता है।

उदाहरण के लिए, इस ANTLR व्याकरण ज्यादा मुसीबत के बिना अपने उदाहरण इनपुट का ख्याल रखता है:

parse 
    : line* 
    ; 

line 
    : Quoted (',' Quoted)* ('\r'? '\n' | EOF) 
    ; 

Quoted 
    : '"' (Atom)* '"' 
    ; 

fragment 
Atom 
    : Parentheses 
    | ~('"' | '\r' | '\n' | '(' | ')') 
    ; 

fragment 
Parentheses 
    : '(' ~('(' | ')' | '\r' | '\n')* ')' 
    ; 

Space 
    : (' ' | '\t') {skip();} 
    ; 

और यह इस विस्तार करने के लिए खाते में बच गए उद्धरण या कोष्ठक लेने के लिए आसान होगा।

"Thanks,", "in advance,", "for("the", "help")" 
"and(,some,more)","data , here" 

इसे इस तरह पार्स हो जाता है:

जब इनपुट की दो पंक्तियाँ निम्नलिखित है कि व्याकरण द्वारा उत्पन्न पार्सर खिला

alt text http://i47.tinypic.com/258otvs.png

आप इस के लिए ANTLR उपयोग करने के लिए पर विचार करें, यदि आप चाहें तो पोस्ट किए गए व्याकरण से पार्सर प्राप्त करने के लिए मैं थोड़ी सी कैसे पोस्ट कर सकता हूं।

संबंधित मुद्दे