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ライブラリはどれですか。

4

2 に答える 2

3

正式な言語、トークン化/文法などに精通している場合は、JavaCCなどのパーサー ジェネレーターを使用できます。JavaCC は、ユーザーが記述した文法ファイルを受け取り、テキスト ファイルを解析して一連のトークンまたは構文ツリーにする Java コードを生成します。この追加ソースをビルドに統合するのに役立つ Maven および Ant 用のプラグインがあります。

ランタイムのみのソリューションには、私が使用したRunCCがあり、良い結果が得られました。(JavaCC ほど高速ではないと思いますが、私の場合、パフォーマンスは良好でした。)

文法ファイルを使用してプレーンテキストを XML に変換するChaperonもあります。

これらに代わる方法は、正規表現と のアドホック ミックスを使用することStringTokenizerです。

パーサー プロジェクトまたは正規表現の準備ができたら、一般的なアプローチは次のようになります。

  1. プレーン テキスト ファイルの文法を記述します。BufferedReader.readLine()プレーン テキスト形式に関する詳細がいくつか欠落していますが、ファイルの行を読み取りStringTokenizer、行をスペースとコンマで部分文字列に分割するために a を使用するだけでよい場合があります。
  2. パーサーから取得する文字列、キーとして使用する最初の文字列、および後続の文字列は、Map に追加する値です。たとえば、擬似コードで

    マップ> マップ = 新しい HashMap>(); 各行に { トークンのリスト = ...; // 行を分割した結果 String key = tokens.get(0); map.add(key, 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
于 2010-04-29T00:31:52.817 に答える
0

Interpreter と Builder を使用できます。

Interpreter はソースを解析し、必要なデータ構造を構築する Builder に渡されるキーと値を識別します。

于 2010-04-26T12:26:56.327 に答える