• ベストアンサー

[000-100]などの文字列を解析したい

よく連番を表す形でFILE[000-100]などという方式がありますが、 これの[000-100]を解析したいです。 具体的には下記の通りです。 例1 "[000-100]"と引数を渡された場合に000、001...099、100と101個の文字列を返す。 例2 "[0-1000]"と渡された場合には0、1...100と1001個の文字列を返す。 例2の場合はいいのですが、例1の場合に桁数のフォーマットの指定方法がわかりません。(桁数、始まりと終わりは変動します) お手数ですがご教授お願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • luckymako
  • ベストアンサー率55% (29/52)
回答No.4

No2です。Iteratorを使った実装もあります。 こちらの方がメモリの消費を抑えられます。 import java.text.DecimalFormat; import java.util.Iterator; import java.util.regex.Matcher; import java.util.regex.Pattern; public class IteratableParser {  public static void main(String[] args) {   String[] srcs = new String[]{    "FILE[000-100]",    "FILE[0-1000]_",    "FILE[00-10]__",    "FILE[10-100]_",    "FILE[100-200]"   };   for(String src : srcs){    for(String num : new Numbers(src)){     System.out.print(num + '、');    }    System.out.println();   }  } } class Numbers implements Iterator<String>, Iterable<String> {  private final int fsti;  private final int lsti;  private final DecimalFormat formater;  private int pointer;  public Numbers(String src){   Pattern p = Pattern.compile("\\[([0-9]++)[-]([0-9]++)\\]");   Matcher m = p.matcher(src);   if(m.find()){    String fsts = m.group(1);    String lsts = m.group(2);    fsti = pointer = Integer.parseInt(fsts);    lsti = Integer.parseInt(lsts);    int digit = fsts.length() < lsts.length() ? fsts.length() : lsts.length();    StringBuffer format = new StringBuffer();    for(int i = 0; i < digit; i++)     format.append("0");    formater = new DecimalFormat(format.toString());   }   else{    fsti = pointer = 0;    lsti = -1;    formater = new DecimalFormat();   }  }  public Iterator<String> iterator() {   return this;  }  public boolean hasNext() {   return pointer <= lsti;  }  public String next() {   return formater.format(pointer++);  }  public void remove() {   throw new UnsupportedOperationException();  } }

tetuya120
質問者

お礼

回答ありがとう御座います。 2の回答にもありましたが下記のようなやり方がある事を知って凄く勉強になりました。 また、Iteratorの実装はよく聞きますが実際に使用したことがなかったのでこちらも目から鱗が落ちました。 これからも勉強していきます。ありがとうございました。 Pattern p = Pattern.compile("\\[([0-9]++)[-]([0-9]++)\\]"); Matcher m = p.matcher(src); String fsts = m.group(1); String lsts = m.group(2);

その他の回答 (3)

  • 11447
  • ベストアンサー率50% (1/2)
回答No.3

もっと簡単な方法があるかもしれませんが, (1)範囲指定の先頭と最後の[]を外す. (2)String.splitを使って-の前後に分ける. (3)Integer.parseIntで001などを数値に変換する という方式でプログラムを書いてみました.結果文字列はArrayListで返します. 以下にプログラムを示します. import java.util.ArrayList; class StringNumber { public static void main(String args[]) { String str="[010-020]"; ArrayList<String> seq=generateString(str); for(int i=0; i<seq.size(); i++) { String s=seq.get(i); System.out.println(s); } } static ArrayList<String> generateString(String str) { String mstr=str.replaceAll("[\\[\\]]",""); String ary[]=mstr.split("-"); int from=Integer.parseInt(ary[0]); int to=Integer.parseInt(ary[1]); ArrayList<String> res=new ArrayList<String>(); for(int i=from; i<=to; i++) res.add(Integer.toString(i)); return res; } }

tetuya120
質問者

お礼

回答ありがとう御座います。 提示していただいたソースだと「10」~「20」が表示されると思います。 [010-020]を与えた場合には「010」~「020」を表示して欲しかったです。

  • luckymako
  • ベストアンサー率55% (29/52)
回答No.2

以下のようなプログラムでいかがでしょうか? import java.text.DecimalFormat; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Parser {  public static void main(String[] args) {   String[] srcs = new String[]{    "FILE[000-100]",    "FILE[0-1000]_",    "FILE[00-10]__",    "FILE[10-100]_",    "FILE[100-200]",   };   for(String src : srcs){    System.out.println(parse(src));   }  }  private static String parse(String src){   Pattern p = Pattern.compile("\\[([0-9]++)[-]([0-9]++)\\]");   Matcher m = p.matcher(src);   if(m.find()){    String fsts = m.group(1);    String lsts = m.group(2);    int fsti = Integer.parseInt(fsts);    int lsti = Integer.parseInt(lsts);    int digit = fsts.length() < lsts.length() ? fsts.length() : lsts.length();    DecimalFormat format = new DecimalFormat(format(digit));    StringBuffer res = new StringBuffer(format.format(fsti));    for(int i = fsti + 1; i <= lsti; i++)     res.append("、").append(format.format(i));    return res.toString();   }   return "";  }  private static String format(int digit){   StringBuffer res = new StringBuffer();   for(int i = 0; i < digit; i++)    res.append("0");   return res.toString();  } }

tetuya120
質問者

お礼

回答ありがとう御座います。 4の改訂版を使用させていただきます。

  • askaaska
  • ベストアンサー率35% (1455/4149)
回答No.1

方法はいくつかあるわね。 ・char配列に分解してif文で仕分ける ・Patternでマッチングする ・MessageFormatでparseする ・substringで仕分ける 楽なのは ・Patternでマッチングする 速度重視なら ・char配列に分解してif文で仕分ける ただし、下手なロジックだと遅くなる。 Patternクラスを使うのがかっこいいわね。 コーディングに自信があるなら charに分解するといいわ。

tetuya120
質問者

お礼

いつも回答ありがとう御座います。 自分で思いついたのはsubstringでごり押し位でしたが、他の回答者様から回答頂いたPatternの方法を使用することにしました。 本来ならばaskaaska様に回答頂いた時点で自分で作成できなければならないんでしょう。。。

関連するQ&A