先日書いた、
oboe2uran.hatenablog.com
これでは、ダメだ
エスケープする文字列が残らない。
だいたい java.util.StringTokenizer なんて古いものは、すでに奨励されていない。
char 型で処理する
public static List<String> tokenToList(String str, char sep, char escape){ List<String> list = new ArrayList<>(); StringBuilder sb = new StringBuilder(); boolean isEscape = false; for(char c:str.toCharArray()) { if (isEscape) { isEscape = false; }else if(c==escape){ isEscape = true; sb.append(c); continue; }else if(c==sep){ list.add(sb.toString()); sb.setLength(0); continue; } sb.append(c); } list.add(sb.toString()); return list; }
InputStream から生成
public static List<String> tokenToList(InputStream in, char sep, char escape) throws IOException{ return tokenToList(new InputStreamReader(in, StandardCharsets.UTF_8), sep, escape); } public static List<String> tokenToList(InputStreamReader in, char sep, char escape) throws IOException{ List<String> list = new ArrayList<>(); StringBuilder sb = new StringBuilder(); try{ boolean isEscape = false; int i; while((i=in.read()) > 0){ char c = (char)i; if (isEscape){ isEscape = false; }else if(c==escape){ isEscape = true; sb.append(c); continue; }else if(c==sep){ list.add(sb.toString()); sb.setLength(0); continue; } sb.append(c); } list.add(sb.toString()); }catch(IOException e){ throw e; } return list; }
Stream<String> が欲しい
public static Stream<String> tokenToStream(String str, char sep, char escape){ Stream.Builder<String> b = Stream.builder(); StringBuilder sb = new StringBuilder(); boolean isEscape = false; for(char c:str.toCharArray()) { if (isEscape) { isEscape = false; }else if(c==escape){ isEscape = true; sb.append(c); continue; }else if(c==sep){ b.add(sb.toString()); sb.setLength(0); continue; } sb.append(c); } b.add(sb.toString()); return b.build(); }
InputSteam から Stream<String> が欲しい
public static Stream<String> tokenToStream(InputStream in, char sep, char escape) throws IOException{ return tokenToStream(new InputStreamReader(in, StandardCharsets.UTF_8), sep, escape); } public static Stream<String> tokenToStream(InputStreamReader in, char sep, char escape) throws IOException{ Stream.Builder<String> b = Stream.builder(); StringBuilder sb = new StringBuilder(); try{ boolean isEscape = false; int i; while((i=in.read()) > 0){ char c = (char)i; if (isEscape){ isEscape = false; }else if(c==escape){ isEscape = true; sb.append(c); continue; }else if(c==sep){ b.add(sb.toString()); sb.setLength(0); continue; } sb.append(c); } b.add(sb.toString()); }catch(IOException e){ throw e; } return b.build(); }
これらで、注意すべきは、エスケープする文字、char で、'\0' を指定した時は、
String の spilit メソッド実行した時に取得できる配列と同じであることだ。
おそらく上のメソッドでそのような指定の実行はしないであろう。
この メソッドは、
GitHub - yipuran/yipuran-core: Java application framework
で、
org.yipuran.util.Tokenstring として作成した。