2012-01-15 15 views
7

में पार्स करने का एक आसान तरीका है, मुझे नीचे दी गई सेवा से प्रतिक्रिया प्राप्त होती है। इसे Map में कैसे पार्स करें? मैंने पहली बार व्हाइटस्पेस पर विभाजित होने का विचार किया लेकिन यह काम नहीं करता है क्योंकि मान में रिक्त स्थान हो सकते हैं उदा। नीचे दी गई प्रतिक्रिया में SA कुंजी के मान को देखें।क्या इस पाठ को मानचित्र

एक विकल्प जिसे मैंने सोचा था कि व्हाइटस्पेस पर विभाजित करना है प्रदान किया गया पिछला वर्ण एक डबल कोट है। हालांकि इस के लिए रेगेक्स लिखना सुनिश्चित नहीं है।

TX = "0000000000108000001830001" FI = "" ओएस = "8" सीआई = "QU01SF1S2032" ऐडवर्ड्स = "एसएसएस" एसए = "1525 विंडवार्ड कोनकोर्स"

उत्तर

4

उद्धरण में पार्स। प्रत्येक मान/मूल्य जोड़ी को खोजने के लिए आप एक नियमित अभिव्यक्ति का भी उपयोग कर सकते हैं, मानते हैं कि प्रत्येक मान उद्धरण में है। मेरा एकमात्र प्रश्न होगा, यदि मूल्य में एम्बेडेड कोट्स हैं तो नियम क्या हैं? (वे उपयोग कर भाग निकले हैं '\' या इस तरह के बावजूद, इस वर्तमान के लिए नीचे में जिम्मेदार नहीं है ...?)

उदाहरण के लिए:

(\w+)="([^"]*)" 

यह भी आप समूहों दे देंगे # 1 और # 2 जिसका उपयोग क्रमशः कुंजी और मूल्य प्रदान करने के लिए किया जा सकता है।

जावा के Matcher.find() विधि का उपयोग करते हुए इसे एक लूप में चलाएं, जब तक कि आप सभी जोड़े नहीं पाते।

नमूना कोड:

String input = "TX=\"0000000000108000001830001\" FI=\"\" OS=\"8\" CI=\"QU01SF1S2032\" AW=\"SSS\" SA=\"1525 Windward Concourse\""; 

Pattern p = Pattern.compile("\\s*(\\w+)=\"([^\"]*)\"\\s*"); 

Matcher m = p.matcher(input); 
while(m.find()){ 
    System.out.println(m.group(1)); 
    System.out.println(m.group(2)); 
} 

आउटपुट:

TX 
0000000000108000001830001 
FI 

OS 
8 
CI 
QU01SF1S2032 
AW 
SSS 
SA 
1525 Windward Concourse 
+2

गीज़, बस एकल उद्धरण का उपयोग करें; इसे टैग किया गया है ग्रोवी :) –

+0

@ डेव न्यूटन - हम इसे ओपी के लिए एक अभ्यास के रूप में छोड़ देंगे। :-) – ziesemer

+0

@ziesemer - +1। लेकिन मुझे "000000000088000001830001" –

2

StreamTokenizer, तेज है, हालांकि मैं quoteChar() सुविधा उपयोग नहीं किया है। उदाहरण here, here और here मिल सकते हैं।

कंसोल:

 
TX=0000000000108000001830001 
FI= 
OS=8 
CI=QU01SF1S2032 
AW=SSS 
SA=1525 Windward Concourse 
Count: 6 
0.623 ms 

कोड:

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.StreamTokenizer; 
import java.io.StringReader; 

/** @see https://stackoverflow.com/questions/8867325 */ 
public class TokenizerTest { 

    private static final String s = "" 
     + "TX=\"0000000000108000001830001\" FI=\"\" OS=\"8\" " 
     + "CI=\"QU01SF1S2032\" AW=\"SSS\" SA=\"1525 Windward Concourse\""; 
    private static final char equal = '='; 
    private static final char quote = '"'; 
    private static StreamTokenizer tokens = new StreamTokenizer(
     new BufferedReader(new StringReader(s))); 

    public static void main(String[] args) { 
     long start = System.nanoTime(); 
     tokenize(); 
     long stop = System.nanoTime(); 
     System.out.println((stop - start)/1000000d + " ms"); 
    } 

    private static void tokenize() { 
     tokens.ordinaryChar(equal); 
     tokens.quoteChar(quote); 
     try { 
      int count = 0; 
      int token = tokens.nextToken(); 
      while (token != StreamTokenizer.TT_EOF) { 
       if (token == StreamTokenizer.TT_WORD) { 
        System.out.print(tokens.sval); 
        count++; 
       } 
       if (token == equal) { 
        System.out.print(equal); 
       } 
       if (token == quote) { 
        System.out.println(tokens.sval); 
       } 
       token = tokens.nextToken(); 
      } 
      System.out.println("Count: " + count); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

अच्छा अद्यतन करने के बाद StreamTokenizer –

+0

मैं सिर्फ 'quoteChar आज़माने के लिए _had_ के बारे में पता करने के लिए()' ; ऊपर से अधिक – trashgod

+0

मुझे लगता है कि यह समाधान अत्यधिक जटिल है। जब तक कोई बड़ी प्रदर्शन बाधा नहीं होती है, तब तक मैं एक सरल समाधान के साथ जाने की सिफारिश करता हूं, जैसे रेगेक्स (और यदि प्रदर्शन _is_ एक बाधा है, तो यह देखने के लिए प्रोफाइल किया जाना चाहिए कि यह रेगेक्स से वास्तव में तेज़ है या नहीं, जो मुझे संदेह है)। – epidemian

3

पाठ का दिखता है ऐसा लगता है यह एक एक्सएमएल हो सकता है कि इनके द्वारा। क्या ऐसा है, या वह पाठ सेवा की कच्ची प्रतिक्रिया है? यदि यह एक एक्सएमएल है आप ग्रूवी के XmlSlurper के साथ आसानी से यह पार्स कर सकते हैं:

def input = '<root TX="0000000000108000001830001" FI="" OS="8" CI="QU01SF1S2032" AW="SSS" SA="1525 Windward Concourse"></root>' 
def xml = new XmlSlurper().parseText(input) 

def map = xml.attributes() 

map चर [CI:QU01SF1S2032, AW:SSS, TX:0000000000108000001830001, OS:8, FI:, SA:1525 Windward Concourse]

होगा अगर यह एक XML नहीं है, आप ziesemer's answer का पालन करें और एक regex का उपयोग कर सकते हैं। कि एक Map उत्पन्न करता है उसके जवाब का एक groovier संस्करण होगा:

def input = 'TX="0000000000108000001830001" FI="" OS="8" CI="QU01SF1S2032" AW="SSS" SA="1525 Windward Concourse"' 
def match = input =~ /(\w+)="([^"]*)"/ 

def map = [:] 
match.each { 
    map[it[1]] = it[2] 
} 

map का परिणाम पहले की तरह ही होगा।

+0

आप यह भी कर सकते हैं: 'def map = (सूची के रूप में मिलान करें) .collectEntries {[(यह [1]): यह [2]]}' –

+0

@tim_yates नाइस! मैंने 'match' ऑब्जेक्ट पर 'collectEntries' को कॉल करने का प्रयास किया, लेकिन इसमें यह विधि नहीं है, केवल मानक पुनरावृत्ति विधियां। मैंने इसे पहले 'सूची' में परिवर्तित करने के बारे में नहीं सोचा था। बीटीडब्ल्यू, एक 'इंजेक्ट' भी चाल = डी कर सकता है – epidemian

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