0

元の(多次元)配列を返すパーサーを書きたくありません

double[][] returned = parse2D(Arrays.deepToString(new double[][]{{1,2}{3,4}}));

同様に、他のパーサーに依存するparse1Dmethod とmethod が必要です。parse3D

これをコーディングしているときに私が遭遇しているいくつかの問題があります。

  • Scanner「[1」や「4]」などのトークンを提供します
  • ScannerusinguseDelimiter("[(\\s*,\\s*)]")は多次元配列の構造を保持しません
  • 適切なグループをキャプチャするためのシングルPatternを取得できないようですMatcher
  • さらに、独自のパーサーを a に書くべきではありませんdouble

次のコードは、私が吐き出した(書いた)種類の作品ですが、次のような文字列も受け入れます"random crap before actual array [1]"

public static Tuple<Matcher, double[]> parse1D(String input) {
    Pattern left = Pattern.compile("\\[");
    Pattern right = Pattern.compile("\\]");
    Pattern comma = Pattern.compile(",\\s*");
    Pattern num = Pattern.compile("[[0-9]+E\\.\\-]+");

    Matcher matcher = left.matcher(input);
    matcher.find();
    List<Double> l = new ArrayList<Double>();
    matcher.usePattern(num);
    while (matcher.find()) {
        MatchResult result = matcher.toMatchResult();
        l.add(Double.parseDouble(result.group()));
        matcher.usePattern(comma);
        matcher.find();
        matcher.usePattern(num);
    }
    double[] ret = new double[l.size()];
    int x = 0;
    for (double d : l) {
        ret[x] = d; x++;
    }
    return new Tuple<Matcher, double[]>(matcher, ret);
} // the matcher is also returned to be used by parse2D...

これはとてもシンプルなはずです!この単純なことを機能させることができないのはなぜですか?! 自分でパーサーを書く必要がありますか? パーサー・コンビネーター・ライブラリーを取得する必要がありますか? 何をすべきか?

4

1 に答える 1

0

これはトリックをしました:

import java.io.IOException;
import java.util.ArrayList;
import javax.json.stream.JsonParser;

public class JSONtry {

private static double[] parse1D(JsonParser parser) throws IOException {
    ArrayList<Double> l = new ArrayList<Double>();

    outerLoop:
        while (parser.hasNext()) {
           JsonParser.Event event = parser.next();
           switch(event) {
              case START_ARRAY: break;
              case END_ARRAY:
                  break outerLoop;
              case VALUE_STRING:
                  l.add(Double.parseDouble(parser.getString()));
                 break;
              default:
                  throw new IOException("Not a 1 dimensional array! Seeing: "+event.toString());
           }
        }
    double[] ret = new double[l.size()];
    for (int i = 0; i<l.size(); i++)
        ret[i] = l.get(i);
    return ret;
}
private static double[][] parse2D(JsonParser parser) throws IOException {
    ArrayList<double[]> l = new ArrayList<double[]>();

    outerLoop:
        while (parser.hasNext()) {
            JsonParser.Event event = parser.next();
            switch(event) {
            case START_ARRAY:
                l.add(parse1D(parser)); 
                break;
            case END_ARRAY:
                break outerLoop;
            default:
                throw new IOException("Not a 2 dimensional array! Seeing: "+event.toString());
            }
        }
    double[][] ret = new double[l.size()][l.get(0).length];
    for (int i = 0; i<l.size(); i++)
        ret[i] = l.get(i);
    return ret;
}
}

ところで:私はgetString(.)代わりに、getInt(.)またはgetBigDecimal(.)許可したいのでNaNPOSITIVE_INFINITY値を使用しています。

最初の配列の後、他の配列の長さがわかるため、多次元配列解析の最適化が可能です。

于 2013-11-18T15:08:38.230 に答える