2016-03-07 9 views
8

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

fieldSeparator : ,
fieldGrouper : "

स्ट्रिंग में बांट दें विभाजन के लिए है: "1","2",3,"4,5"

मैं इसे प्राप्त करने में सक्षम हूँ इस प्रकार है:

String record = "\"1\",\"2\",3,\"4,5\""; 
String[] tokens = record.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"); 

आउटपुट:

"1" 
"2" 
3 
"4,5" 

अब चुनौती यह है कि fieldGrouper (") विभाजन टोकन का हिस्सा नहीं होना चाहिए। मैं इसके लिए रेगेक्स को समझने में असमर्थ हूं।

विभाजन की उम्मीद उत्पादन होता है:

1 
2 
3 
4,5 
+0

मुझे लगता है कि यह चार-दर-चार कर

यहाँ एक Java sample code है वास्तव में अधिक पठनीय और निश्चित रूप से तेज़ होगा। और एल्गोरिदम जितना आसान हो उतना आसान होता है। और '' 'अपवाद को संभालना आसान है जो संभवतः जल्दी या बाद में दिखाई देगा। – Dariusz

+0

हम पूछ सकते हैं कि आप विकृत छद्म JSON इनपुट के साथ क्यों काम कर रहे हैं? उद्धरणों के साथ फंसेपन से निपटने में मुश्किल होती है और आपके लिए स्रोत को साफ करना बेहतर हो सकता है। –

उत्तर

4

अद्यतन:

String[] tokens = record.split("(,*\",*\"*)");

परिणाम:
Image Link

प्रारंभिक समाधान:
(काम नहीं करता है @.split विधि)

यह RexEx पैटर्न वर्गों को अलग होगा आप चाहते हैं:
(?:\\")(.*?)(?:\\")

यह का उपयोग करता है गैर पर कब्जा समूहों के जोड़े को अलग करने के उद्धृत उद्धरण, और एक कैप्चरिंग समूह के बीच में सब कुछ अलग करने के लिए।

यहाँ देखें: Live Demo

+2

यह रेगेक्स '3' या किसी भी अन्य मान से मेल नहीं खाता है जो' "..." के साथ संलग्न नहीं है। –

+0

@ WiktorStribiżew मैंने समाधान अपडेट किया, लेकिन मेरे शुरुआती समाधान में मैंने माना कि '#" 'पैटर्न सुसंगत था। मुझे एहसास नहीं हुआ कि '3' पर कब्जा नहीं किया गया था, और अभी भी आश्चर्य है कि @rvd जानबूझकर' 3' के लिए एक अलग प्रारूप है। किसी भी तरह से, नया समाधान काम करता है। – Enteleform

+0

क्षमा करें, लेकिन आपका दूसरा सॉल्शन इनपुट के लिए काम नहीं करेगा जैसे 1,2 और 1 और 2 अलग-अलग संख्याएं हैं। –

0

मेरे प्रस्ताव:

record = record.replaceAll("\",", "|"); 
record = record.replaceAll(",\\\"", "|"); 
record = record.replaceAll("\"", ""); 

String[] tokens = record.split("\\|"); 

for (String token : tokens) { 
    System.out.println(token); 
} 
2

मेरे सुझाव:

"([^"]+)"|(?<=,|^)([^,]*) 

regex demo देखें। यह "..." से तारों की तरह मिलान करेगा और समूह 1 में केवल कैप्चर के बीच में कैप्चर करेगा, और उसके बाद स्ट्रिंग या कॉमा के बाद , के अलावा वर्णों के समूह 2 अनुक्रमों में मिलान और कब्जा करेगा।

String s = "value1,\"1\",\"2\",3,\"4,5\",value2"; 
Pattern pattern = Pattern.compile("\"([^\"]+)\"|(?<=,|^)([^,]*)"); 
Matcher matcher = pattern.matcher(s); 
List<String> res = new ArrayList<String>(); 
while (matcher.find()){      // Run the matcher 
    if (matcher.group(1) != null) {   // If Group 1 matched 
     res.add(matcher.group(1));   // Add it to the resulting array 
    } else { 
     res.add(matcher.group(2));   // Add Group 2 as it got matched 
    } 
} 
System.out.println(res); // => [value1, 1, 2, 3, 4,5, value2] 
+0

बेहतर सुझाव यह है कि वह अपना स्रोत डेटा IMHO साफ़ करता है। –

1

मैं इस तरीके का उपयोग प्रकार के साथ की कोशिश करेंगे:

String record = "\"1\",\"2\",3,\"4,5\""; 
record = record.replaceAll("\"?(?<!\"\\w{1,9999}),\"?|\""," "); 
String[] tokens = record.trim().split(" "); 
for(String str : tokens){ 
    System.out.println(str); 
} 

आउटपुट:

1 
2 
3 
4,5 
+0

मुझे अंततः समान वर्कअराउंड का उपयोग करना पड़ा, यानी, पहले विभाजित करें और फिर प्रत्येक टोकन से कोट्स (यदि मौजूद है) को हटा दें। – rvd

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