• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:文字列を分割するクラスについて)

文字列を分割するクラスの開発方法とアドバイス

このQ&Aのポイント
  • 文字列を分割するクラスを開発する際、StringTokenizerクラスは有効な方法です。例えば、住所の分割アルゴリズムを実装する場合、StringTokenizerを使用することで住所地名の途中や番地の途中での分割を回避できます。
  • 以下はStringTokenizerを使用した住所分割の実装例です。住所を80文字の配列として受け取り、20文字ずつの4等分に分割してカンマ区切りの文字列を生成します。
  • StringTokenizer以外の便利な文字列分割クラスとしては、正規表現を使用する方法もあります。正規表現を使うことで、より柔軟な分割条件を指定することができます。

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

  • ベストアンサー
  • salsberry
  • ベストアンサー率69% (495/711)
回答No.5

> 添字とかjavaの共通語だと思うのですが > イメージはあるものの理解できてません。 これは困りました。Java以外の言語でも配列を使ったプログラミングをしたことはありませんか? JavaやCを例にすると配列アクセス時に[ ]の中に書く式のことを添字(英語由来のカタカナ語だとインデックス)と言います。 下記のコードではargs[i]の[ ]の中のiが添字です。 public static void main(String[] args) { for (int i=0; i<args.length; i++) { System.out.println(args[i]); } } > 恐縮ですがなにか参考になる使用例が > あるサイトはご存知でしょうか? 配列やループの例なら大概のJava言語入門書や入門サイトの初めのほうに載っているでしょう。 > String[] name = "jflute"; こういう書き方はできません。左辺がStringの配列なのに右辺がStringなので型が合わず代入は不可能です。 ここまで書いてきましたが、今になってこの文字列の分割に正規表現が使う手もあると思い至りました。クラス名で言うとjava.util.regex.Patternとjava.util.regex.Matcherを使います。これらのクラスの使い方は「Java 正規表現」で検索して見つかる入門サイトをいくつか眺めて勉強してください(ここの回答欄では説明し切れません)。 "^.{1,20} "という正規表現を使えば、文字列の先頭から始まって全角空白で終わる最大21文字(最後の全角空白を含む)にマッチさせることができます。 でも、あまり単純な話ではないのでANo.2に書いた方法と比べてどちらを理解するのが楽かと言われると微妙なところです。

yairi1106
質問者

お礼

下記のようなサンプルを参考にして やろうとしてました。 正規表現はVBAでも勉強したかった 構文ですので "^.{1,20} "はおぼえておいて こちらも勉強してみます。 /* パターン2の正規表現 (2)-1.正規表現のパターンに適合するか確認する文字列text2を 生成します。 (2)-2.compileメソッドで正規表現をコンパイルします。 (2)-3.splitメソッドで引数に指定された文字列を正規表現に合 わせ分割し、分割された文字列を配列で返します。 (2)-4.分割された文字列をforループを使用し、表示します。 */ String text2 = new String("java1 java2 java3"); Pattern pattern2 = Pattern.compile("\\s"); String[] splitStr = pattern2.split(text2); for (int i = 0; i < splitStr.length; i++) { System.out.println(splitStr[i]); } System.out.println("---------------" + "\n");

yairi1106
質問者

補足

コメントありがとうございます。 JAVA以外は、VBAをかじってるぐらいです。 添字に関しては認識しました。 参考書等の繰り返し文のサンプルなどに あるようなループだったんですね。 参考書とアドバイスいただいた説明でやってみます。 > String[] name = "jflute"; 気をつけます。 これは凡ミスです。 ここでご質問する前に下記のようなサンプルで 文字列分割を考えてましたが 私にはちょっと早いようです。 とりあえずアドバイスいただいた方向ですすめてみます。 ですが"^.{1,20} "という正規表現の方法はメモしておいて 正規表現のほうも今後もしくは並行して勉強してみる予定です。 import java.util.regex.*; public class ExRegex { public static void main(String[] args) { /* パターン1の正規表現 (1)-1.正規表現のパターンに適合するか確認する文字列text1を 生成します。 (1)-2.compileメソッドで正規表現をコンパイルします。 (1)-3.matcherメソッドで引数に正規表現の適合を確認する文字 列を指定し、Matcherオブジェクトを生成します。 (1)-4.matchesメソッドで正規表現に適合するかを確認します。 適合する場合trueを返します。 */ String text1 = new String("java1 java2 java3"); Pattern pattern1 = Pattern.compile("(java\\d)\\s(java\\d)\\s(java\\d)"); Matcher matcher1 = pattern1.matcher(text1); System.out.println(matcher1.matches()); System.out.println("---------------" + "\n");

その他の回答 (5)

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.6

ANo.4のお礼にある質問について。 情報が全く足りません。そこに書かれていることだけ読んで何が起こっているのか分かったら超能力者です。 30件あるというレコードは1レコードずつstrAry[0], strAry[1], ...にそれぞれ代入されているのか、それとも1レコードを部分要素に分割したものがstrAry[0], strAry[1], ...に代入されているのかも分かりません。以前の質問から後者かなと想像はできますが。 なぜstrAry[2]がないのかも不明ですが、それが関係しているのかどうかも全く分かりません。 あとは、入力ファイルの4レコード目のデータをstrAry[]に分割する処理がいまく行かなくてそこで異常終了しているだけかも知れませんし。 元々の問題(文字列の分割)と全く関係のない内容になっているので、新しい質問を立てるべきでしょう。その際、ファイルの読み込み、strAry[]への代入からファイル書き出しまでの流れが全て分かるようにコードを示してください。

yairi1106
質問者

補足

分かりました。 整理してから改めて新規でご質問させていただきます。

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.4

> (E)配列の添字を1ずつ増やした状態でA~Dを繰り返す作業がどうせればよいのか > 分かりません。 配列アクセスの添字に変数を使い、その変数の値を増やしながらループすればいいだけですけど。

yairi1106
質問者

お礼

たびたびすいません。 例えば下記のように書いた場合に 30レコードあるテキストデータを入出力した際に 3件レコードしか出力されなくなるのですが 添字の書き方が間違っているのでしょうか?? 何が原因と考えられますでしょうか?? out.print(strAry[0]+" "+strAry[1]+","+strAry[3]+" "+strAry[4]);

yairi1106
質問者

補足

コメントありがとうございます。 >配列アクセスの添字に変数を使い、その変数の値を増やしながらループすればいいだけですけど。 添字とかjavaの共通語だと思うのですが イメージはあるものの理解できてません。 下記のような使用例をイメージして 考えればいいのでしょうか?? 恐縮ですがなにか参考になる使用例が あるサイトはご存知でしょうか? String[] name = "jflute"; String cutStr; if (name.length() > 19 { // 19文字を超える(20文字以上なら) cutStr = ( ); // 20文字目までを切り取る } else { cutStr = name; // 切り取りようがない、もしくは、切り取る必要がない }

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.3

ANo.2の訂正。 (C) strAry[0]に、strAry[0]+" "+strAry[i+1]を代入する。   ↓ (C) strAry[0]に、strAry[0]+" "+strAry[1]を代入する。 > まずはstrAry[0]strAry[1]strAry[2strAry[3]4つ宣言して split()で分割した部分文字列は4つではなくてもっと多いかもしれませんし、split()を使うならそのような宣言をする必要はない(そもそも、配列の要素を一つずつ宣言することはできない)わけですが…

yairi1106
質問者

補足

アドバイスどうもありがとうございます。 なるほど。と言っておきながらソースで考えると 文字列分割の便利なクラスを参考にして その後は詳しく聞くつもりはなかったのですが・・・ 対処に時間がかかりそうです。 String str = new String(住所漢字); String[] strAry = str.split(" "); String name = str; のようにして if (name.length() > 19) { // 19文字を超える(20文字以上なら) のあとに (E)配列の添字を1ずつ増やした状態でA~Dを繰り返す作業がどうせればよいのか 分かりません。

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.2

ANo.1に書いたことですが、例外的な入力データはないという前提でこんな感じでどうでしょうか? String addr = "aaaaaaaaa bbbbbbbbbb cccccc ddddddddddddddd eee ffffff"; String[] strAry = addr.split(" "); (A) strAry[1]がnullなら終了。 (B) strAry[0]の長さとstrAry[1]の長さの和が19以上のときは(E)へ。 (C) strAry[0]に、strAry[0]+" "+strAry[i+1]を代入する。strAry[1]にstrAry[2]を代入、strAry[2]にstrAry[3]を代入、…のようにstrAry[]の要素を前に詰める。strAry[]の最後の要素にはnullを入れる。 (D) (A)に戻る。つまり、strAry[0]の長さが20を超えない範囲で、どんどんstrAry[1]以下の文字列をstrAry[0]に連結していく。 (E) 配列の添字を1ずつ増やした状態で(A)~(D)の内容を繰り返す。

yairi1106
質問者

補足

ご教授どうもありがとうございます。 なるほど。アドバイス頂いた方法で まずはstrAry[0]strAry[1]strAry[2strAry[3]4つ宣言して if文で構文を書いてみます。 もうベストアンサーにさせて頂く予定ですが 検証後にご報告させて頂いてから クローズとさせていただきますので よろしくお願い致します。

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.1

いくつか確認させてください。 ・「4等分にするアルゴリズムを考えています」とありますが、「等分(等しい長さで分割)」ではなくて「最大で20文字に収まるように分割(等しい長さになっていなくても良い)」という意味ですか? ・入力される住所は、予め全角空白「 」で必ず区切られているのですか? もしそうでないとすると、「住所の途中や番地の途中で区切らない」を自動で判断するのは困難です。 ・全角空白を含まない文字列が20文字以上続いていた場合はどうするのですか? そういう入力はないと思っていいのですか? ・分割する数は4で、分割した各文字列は最大20文字と決まっているのですか? 「80桁すべてに文字は格納されているときは20桁の4等分にする」とありますが、それよりもっと短い文字列の場合でも前提を満たせない文字列があり得ます。たとえば入力された住所が「4文字 17文字 10文字 11文字 10文字」(空白を含めて56文字)のように区切られていた場合はどういう結果になりますか? > StringTokenizer st = new StringTokenizerのクラスは開発に有効でしょうか? そんなもの持ち出さなくても、入力文字列が予め全角空白で必ず区切られているならば、全角空白でStringをsplit()してから短い文字列をつなぎ直せばいいだけのような気がします。 もっとも、上に挙げたように前提条件を満たせない入力文字列がありそうなので、もっと制約(××のような入力はあり得ないので無視して良い、など)がないと回答不能な問題です。 また、「住所のメソッドでの開発についてご質問がございます」とか「住所の配列は全角80(半角160)に格納される」などの文は日本語として意味が取りにくいです。もしかして質問者さんの母国語が日本語でない場合はある程度仕方がありませんが、がんばって意味の通じる文を書いてください。

yairi1106
質問者

補足

いつもお世話になります。 >最大で20文字に収まるように分割(等しい長さになっていなくても良い)」という意味ですか? なるべく回答者に対して認識できるよう努力しますが その通りです。 区切られる文字の前には必ず全角空白で区切られている仕様です。 基本的に全角80桁の領域に文字が入力されていて後列に余った全角空白は 削るイメージです。 >全角空白を含まない文字列が20文字以上続いていた場合はどうするのですか? そういう入力はないと思っていいのですか? 説明不足でしたが、ないと思って構いません。 >たとえば入力された住所が「4文字 17文字 10文字 11文字 10文字」(空白を含めて56文字)のように区切られていた場合はどういう結果になりますか? このような例外の場合は、(基本ありえませんが)住所の途中で改行してもかまいません。 >住所の配列は全角80(半角160)に格納される バイナリデータから、汎用機でCSVデータを生成される場合の 社内共通語で話してしまいました。 それとご回答者に対して、わかりやすく説明する努力を 致しますが、今回は解決まで面倒見ていただくというよりは 便利なクラスがあれば参考程度にお聞きしたかったということは 報告しておきます。

関連するQ&A

専門家に質問してみよう