2016-12-21 8 views
0

テキストファイルからデータを読み込んでセットに保存するタスクが与えられました。テキストファイルは、特定の商品説明とその価格、数量、合計金額を含む架空の請求書を表します。私はアイテムの名前と価格が必要です。テキストファイルは次のようになります。数字と文字の両方を含むテキストファイルを同じ行に読み込んで解析する

Item_name Item_price(float value with comma as format symbol) Quantity(int) Total(float) 
Item_name Item_price(float value with comma as format symbol) Quantity(int) Total(float) 

(テキストファイルには複数の項目が含まれています)。また、アイテムには名前に数字が含まれることもあります。 LG 4k TV 1000U)。

私はこのようにそれを解決しようとした:

private void readAndSave(Path file) { 
    try (BufferedReader br = new BufferedReader(new InputStreamReader(
      new BufferedInputStream(new FileInputStream(file.toString()))))) { 


     Set<Item> items = new TreeSet<>(); 
     String line; 
     while ((line = br.readLine()) != null) { 


      float price = 0, numb; 
      boolean priceFound = false; 
      String name = ""; 
      String[] lineElements; 
      lineElements = line.split(" "); 

      for(String temp: lineElements) { 
       if((numb = getNumberRepresentation(temp)) != -1) { 
        if(!priceFound) { 
         price = numb; 
         priceFound = true; 
        } 
        break; 
       } 

       name += temp + " "; 
      } 
      items.add(new Item(name, price)); 

     } 
    } catch (FileNotFoundException fe) { 
     System.out.println("File not found!"); 
    } catch (IOException e) { 
     System.out.println("Error while opening/writing files!"); 
    } 

} 

クラスItemは、アイテムの名前と価格を表す2つの変数(文字列、フロート)を含み、Comparableを拡張します。

そして、ここでは、私はスキップすることができます価格が発見された場合、その名前もすでに見つけられなければならない、ロジック、およびラインから他のすべての文字列を使用しようとした

private float getNumberRepresentation(String temp) { 
    try { 

     DecimalFormatSymbols symbols = new DecimalFormatSymbols(); 
     symbols.setDecimalSeparator(','); 
     DecimalFormat format = new DecimalFormat("0.##"); 
     format.setDecimalFormatSymbols(symbols); 
     return format.parse(temp).floatValue(); 

    } catch(Exception e) { 
     return -1; 
    } 
} 

getNumberRepresentation方法であり、 。ここで問題となるのは、アイテムの名前から価格(前の例では1000U)を取得することがあることです。この問題を解決するために、より効率的な方法がありますか?

編集:ファイルのサンプル

Escape from Paradise City 70,00 1135 79450,00 Sony ITC60, TV cabel 111,26 111 12349,86

+0

1つの提案へあなたの既存のコードは...あなたを一時的に価値あるものと解釈するために '試してキャッチする' TryParse() などを使用してください。 bool結果= Int32.TryParse(値、アウト数); if(result) { Console.WriteLine( "{0}"を{1}。 "、value、number)に変換します。 } else { // if(value == null)value = ""; Console.WriteLine( "'{0}'の変換を試みましたが失敗しました。"、 値== null? "":値); } – Gwasshoppa

+0

テキストファイルの外観を制御できますか?あなたはファイルをタブ区切りにすることができますか?そして、あなたはタブで分割しています。 "(スペース。 – Gwasshoppa

+0

申し訳ありませんが、残念ながら私はテキストファイルを制御できません。 – kolsdj

答えて

0

あなたはjava.util.regex.Patternを使用する必要があり、コストのためのコストと正規表現の一致のための正規表現の試合前に、すべてを取得。私は###の##のような名前に何もないと仮定します。##は数字です。 (正規表現では\ dで表されます)。各行の

Pattern p = Pattern.compile("(.*?) (\\d*,\\d*)"); 

:行を読む前に

チュートリアルでは、それは次のようになりますhere.

を見つけることができます

Matcher m = p.matcher(line); 
if (m.matches() && m.groupCount() == 2) { 
    name = m.group(1); 
    price = getNumberRepresentation(m.group(2)); 
} else { 
    // line doesn't match the pattern, handle the exception! 
} 
+0

私はあなたのアプローチを(私がそれを正しく理解していると仮定して)使用しようとしましたが、名前のためには合計の前にすべてが得られ、価格には合計が得られます。コードは以下の通りです: 'lineElements = line.split(" "); \t \t \t \tマッチャm = p.matcher(行); (m.matches()&& m.groupCount()== 2){ \t \t \t \t名= m.group(0)であれば \t \t \t \t。 \t \t \t \t price = getNumberRepresentation(m.group(1));他 \t \t \t \t} { \t \t \t \t \tのSystem.out.println( "回線エラー。"); \t \t \t \t} – kolsdj

+0

私の解説は良く書かれていません。行を分割する前に言っているのではなく、読んでから各行ごとに言っておくべきです。これを反映する答えを修正します。また、あなたのパターンが貪欲でないことを確認してください。 "。*?"の代わりに "。*"。この回答の最初のバージョンは、あなたが話している振る舞いを与える欲張りでした。 –

関連する問題