2010-04-26 65 views
5

我正在解析純文本並將其轉換爲鍵值對。 例如,純文本:解析純文本到某些結構化對象

some_uninteresting_thing 
key1 valueA, some_uninteresting_thing valueB 
key2 valueD 
key3 some_uninteresting_thing valueE 
key4 valueG(valueH, valueI) 
key5 some_uninteresting_thing 

和可能的映射:

Map(

key1 ->(valueA, valueB,valueC), 
key2 ->(valueD, valueE), 
key3 ->(valueF) 
key4 ->(valueH, valueI) 

... 
) 

的AMD結果將是:

key1 ->(valueA, valueB) 
key2 ->(valueD) 
key4 ->(valueH, valueI) 

(KEY5不應被映射,因爲沒有合適的值。正如你所看到的純文本是寬鬆的。什麼java庫將幫助處理這個?

+1

謹 'KEY1值a,VALUEB,valueC' 地圖1個鍵/值對的線( 'KEY1'=> '值a,VALUEB,valueC')或3鍵/值對( 'KEY1'= >'valueA'和'key1'=>'valueB和'key1'=>'valueC')? – 2010-04-26 12:04:27

+1

你的代碼應該如何處理你的例子的第一行? 'some_uninteresting_thing'是沒有價值的關鍵,或者是什麼?在處理最後一行時如何考慮這一點? – 2010-04-26 12:04:52

+3

如何區分「無趣」文本和「有趣文本」。例如,如果第一行是「它是生命,那麼Jim」是無趣的,或者它是關鍵=「它是」,valueA =「life」,valueB =「Jim」? – 2010-04-26 12:06:51

回答

3

如果您熟悉正式語言,標記/語法等,您可以使用解析器生成器,如JavaCC。 JavaCC使用您編寫的語法文件並生成將代碼解析爲一系列令牌或一個sytax樹的java代碼。有Maven和Ant的插件可以幫助將這個額外的源代碼集成到你的構建中。

對於僅運行時解決方案,有RunCC,我已經使用了它,並取得了良好的結果。 (我懷疑它沒有JavaCC那麼快,但對於我的情況來說性能還是不錯的。)

還有Chaperon,它使用語法文件將純文本轉換爲XML。

這些替代方法是使用正則組合的正則表達式和StringTokenizer

隨着解析器項目或正則表達式武裝和準備好了,你的一般的方法是那麼這樣的:

  1. 寫你的純文本文件的語法。您的純文本格式缺少一些詳細信息,但您可以簡單地使用BufferedReader.readLine()讀取文件的行,並使用StringTokenizer將行分隔爲空格和逗號的子字符串。
  2. 您從解析器中獲得的字符串,用作鍵的第一個字符串以及後續的字符串都是您添加到Map中的值。例如。僞代碼

    Map> map = new HashMap>();每行有 { List tokens = ...; //分割結果 String key = tokens.get(0); map.add(鍵,tokens.sublist(1,tokens.size());}

    即使解析器不過濾無趣文本,稍後將過濾

  3. 構建。解析器與上述項目一起解析地圖文件格式,再次,您可以使用正則表達式和StringTokenizer構建一個簡單的解析器,使用解析器構建地圖,該地圖具有與上述相同的簽名,即Map<String,List<String>>.

  4. 最後,根據允許的值映射過濾輸入映射。

就是這樣。

Map<String,List<String>> input = ...; // from step 1. 
    Map<String,List<String>> allowed = ...; // from step 3. 
    Map<String,List<String>> result = new HashMap<String<list<String>>(); // the final map 
    for (String key : input.keySet()) { 
     if (allowd.contains(key)) { 
     List<String> outputValues = new ArrayList(); 
     List<String> allowedValues = allowed.get(key); 
     List<String> inputValues = input.get(key); 
     for (String value: inputValues) { 
      if (allowedValues.contains(value)) 
       outputValues.add(value); 
     } 
     if (!outputValues.isEmpty()) 
      output.put(key, outputValues); 
     } 
    } 
    // final result in filter 
0

您可以使用解釋器和生成器。

解釋器解析源代碼,並識別傳遞給Builder的鍵和值,這些鍵構造您所需的任何數據結構。