発端は JSON の値が配列の場合、'[ ] ' の書式の文字列データからリストを導き出すのに、
そもそも原始的にはどうなんだろうと思ったことでした。
かなり昔、Java のバージョンも小さい 10年以上前であれば、カンマ区切りで
文字列 String の split メソッドで String[] にして
ごにょごにょとバグが発生しそうなコードを書いてたと思います。
[ 25, 7, ,, "12", 0, -8 , ]
こんなテキストから、Integer の List を作成する。
もっとも自然に考えれば、数値の正規表現でマッチ→ 変換です。
Java8の正規表現で、去年書いた Pattern to Stream - Oboe吹きプログラマの黙示録
を利用、もしくは、
https://github.com/yipuran/yipuran-core/tree/master/src/main/java/org/yipuran/regex
を使って、、、
Java8まで、(数値の正規表現で)
List<Integer> list = StreamSupport.stream(new MatcherItrator(Pattern.compile("\\-{0,1}\\d+").matcher(str)), false) .map(e->e.toString().trim()).filter(e->!"".equals(e)) .map(e->Integer.parseInt(e)) .collect(Collectors.toList());
これで充分ですが、数字以外を除去する考え方なら、
List<Integer> list = StreamSupport.stream(new MatcherItrator(Pattern.compile("[^,\"\\[\\]]+").matcher(str)), false) .map(e->e.toString().trim()).filter(e->!"".equals(e)) .map(e->Integer.parseInt(e)) .collect(Collectors.toList());
でも、Google GSON を使えば、、
List<Integer> list = StreamSupport.stream(new JsonParser().parse(str).getAsJsonArray().spliterator(), false) .filter(e->!e.isJsonNull()).map(e->e.getAsInt()) .collect(Collectors.toList());
と短くなります。
Java9からの Stream<MatchResult> java.util.regex.Matcher.results() を使うなら、
List<Integer> list = Pattern.compile("[^,\"\\[\\]]+").matcher(str).results() .map(e->e.group().trim()) .filter(e->!"".equals(e)) .map(e->Integer.parseInt(e)) .collect(Collectors.toList());
あるいは、
List<Integer> list = Pattern.compile("\\-{0,1}\\d+").matcher(str).results() .map(e->Integer.parseInt(e.group())) .collect(Collectors.toList());
と書けます。
Integer のリストは、GSON 使って JSON として解析させようが、正規表現で解析させようが
結果を同じにすることはできます。
でも文字列の配列は、そうはいきません。。
String str = "[ \"a\", \"\", ,, \"b\", \" c\" , ]";
を例にしてみます。
Java8 正規表現で、、
List<String> list = StreamSupport.stream(new MatcherItrator(Pattern.compile("[^,\"\\[\\]]+").matcher(str)), false) .map(e->e.toString()) .map(e->e.toString().trim()) .filter(e->!"".equals(e)) .collect(Collectors.toList()); list.stream().forEach(e->{ System.out.println("[" + e + "]"); });
結果
[a] [b] [c]
Googl gson を使って、、、
List<String> list = StreamSupport.stream(new JsonParser().parse(str).getAsJsonArray().spliterator(), false) .map(e->e.isJsonNull() ? "" : e.getAsString()) .collect(Collectors.toList()); list.stream().forEach(e->{ System.out.println("[" + e + "]"); });
結果
[a] [] [b] [ c]
結果は、gson の方が厳密です。
Java9での正規表現、results() の使用、、
List<String> list = Pattern.compile("[^,\"\\[\\]]+").matcher(str).results() .map(e->e.group().trim()) .filter(e->!"".equals(e)) .collect(Collectors.toList()); list.stream().forEach(e->{ System.out.println("[" + e + "]"); });
結果は、もちろん
[a] [b] [c]
数値ではなく、テキストで厳密な、配列JSONからリストへの変換を考えると、
正規表現よりも、Google gson の方が良いような気がします。