質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

4回答

13070閲覧

JAVAでCSVファイルを読み込み、文字列のデータ型をチェックする方法

kumakumatan

総合スコア213

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

1クリップ

投稿2016/06/15 02:13

CSVファイル内容
社員番号(ABC1582),社員名(漢字), 任意番号(124566),携帯番号(xxx-xxxx-xxxx)

読み込んでデータを配列にセットする。
その時、任意番号が整数型(int)かのチェック、携帯番号に(-)が含まれている
かのチェックをしたいのですが、そのような事は可能でしょうか。
チェックで引っかかったものをメッセージを表示するようにしたいです。
下記にサンプルコードを記載します。

JAVA

1package ren01; 2 3import java.io.BufferedReader; 4import java.io.File; 5import java.io.FileInputStream; 6import java.io.FileNotFoundException; 7import java.io.IOException; 8import java.io.InputStreamReader; 9import java.io.UnsupportedEncodingException; 10 11public class read02 { 12 13 public static void main(String[] args) { 14 // ここにコードを挿入 15 try { 16 // ファイルのパスを指定してオブジェクトを生成。 17 File file = new File("C:\\ws01\\ren01\\src\\ren01\\sample.csv"); 18 // 入力ストリームを生成。( FileNotFoundException が発生 ) 19 FileInputStream input = new FileInputStream(file); 20 /* 入力ストリームの読み込み。 ( UnsupportedEncodingException が発生 ) 21 * ここでCSVファイルの文字コードを設定しないと文字化けします。 */ 22 // 読み込むファイルの文字コード(SJIS) 23 InputStreamReader stream = new InputStreamReader(input, "SJIS"); 24 // バッファに取り込み。 25 BufferedReader buffer = new BufferedReader(stream); 26 27 String line; 28 29 /* readLine()でバッファの1行を取り出す作業を、読み込める行が無くなるまでwhile文で実行。 30 * line = buffer.readline() でBufferedReaderが保持する一行を取出しているので、ループする毎に書き変わります。 */ 31 while((line = buffer.readLine()) != null) { 32 // 取出した1行の文字セットを変換して新たに文字列を生成。 33 byte[] b = line.getBytes(); 34 // String で UnsupportedEncodingException が発生 (変換したい文字コード:UTF-8) 35 line = new String(b, "UTF-8"); 36 // 文字列をカンマ区切りで配列に分けて要素ごとに出力。 37 // 16行目、line.splitの第2引数に"-1"を指定しないと、" 3,test, " の行の配列は " 3,test " の2つになってしまい他の行と要素数が 38 // 違うため、出力結果の様にはなりません。 39 String[] columns = line.split(",", -1); 40 41 for(int j = 0; j < columns.length; j++) { 42 System.out.println(j + " : " + columns[j]); 43 } 44 45 System.out.println(""); 46 47 } 48 49 // 開いたストリームとバッファを閉じて関連するシステム・リソースを解放します。 ( IOException が発生 ) 50 input.close(); 51 stream.close(); 52 buffer.close(); 53 54 } catch (UnsupportedEncodingException | FileNotFoundException e) { 55 e.printStackTrace(); 56 57 } catch (IOException e) { 58 e.printStackTrace(); 59 60 } 61 62 } 63} 64

宜しくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

他の回答で「正規表現を使う」のアイデアに合意します。

String.matches()は今回のケースでは性能が良くないので、
java.util.regexのPatternとMatcherを使うのをおすすめします。
以下、正規表現の使用例です。

Java

1Pattern p1 = Pattern.compile("^[0-9]+$"); // 数字 2Pattern p2 = Pattern.compile("^[0-9]{3}-[0-9]{4}-[0-9]{4}$") // 携帯番号 3 : 4for(int j = 0; j < columns.length; j++) { 5 System.out.println(j + " : " + columns[j]); 6 if(j==2 && p1.matcher(columns[j]).matches()==false){ 7 System.out.println("任意番号がおかしい: "+column[j]); 8 }else if(j==3 && p2.matcher(columns[j]).matches()==false){ 9 System.out.println("携帯番号がおかしい: "+column[j]); 10 } 11}

投稿2016/06/15 03:44

編集2016/06/15 04:48
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kumakumatan

2016/06/15 03:54

ありがとうございます。 このパターンで、社員番号(ABC1582),社員名(漢字),もチェックするとどうなりますか?社員番号は英数字(大文字もOK)、社員名は文字列型(String)です。 宜しくお願いします。
退会済みユーザー

退会済みユーザー

2016/06/15 03:57

本題とは関係ありませんが、 ファイルをクローズする処理は、例外がスローされた場合も行う必要がある場合があります。 なので、 FileInputStream input = null; InputStreamReader stream = null; BufferedReader buffer = null; try{ : }catch(...){ : }catch(...){ : }finally{ try{ if(buffer != null) buffer.close(); }catch(IOException e){ ex.printStackTrace(e); } } buffer.close()を実行すれば、stream.close()とinput.close()も内部で実行されるため 「if(buffer != null) buffer.close()」だけでも良いのです。 もっと簡潔に書く方法があるのですが、本題からずれるので今回は割愛します。
退会済みユーザー

退会済みユーザー

2016/06/15 04:09 編集

Pattern.compile("^[a-zA-Z]{3}[0-9]{4}$") //社員番号 社員名はどんなパターンになっていますか? 単純に数字が含まれていないというのを確認するだけであれば、次の正規表現になるでしょうか(アルファベットは容認)。 Pattern p = Pattern.compile("^[^\\d]+$"); // 簡単な正規表現 Pattern p = Pattern.compile("^[^\\d]+ [^\\d]+$"); // 姓と名の間に半角空白を入れる場合の正規表現 社員名がローマ字表記なのか漢字なのか、また姓と名の間に全角空白/半角空白のどちらを使っているのか等の細かい仕様が決まっているのであれば、合わせて正規表現が変わってきます。 正規表現の詳細は、次のPatternのjavadocを参照されるのが良いです。 http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html
kumakumatan

2016/06/15 06:53

ありがとうございます。 教えていただいた事を踏まえて、作成しました。 この中で「Pattern p3 = Pattern.compile("^[^0-9]*$"); //社員番号(英数字)」 の正規表現がわかりません。やりたい事は英数字が1文字でもあればOKとしたいのですが。どのようにしたらよろしいでしょうか? ====JAVA================== package ren01; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.regex.Pattern; public class read3 { public static void main(String[] args) { // ここにコードを挿入 try { String path = new File(".").getAbsoluteFile().getParent(); //System.out.println(path + "\\sample.csv"); String path2 = (path + "\\sample.csv"); //System.out.println(path2); // ファイルのパスを指定してオブジェクトを生成。 //File file = new File("C:\\ws01\\ren01\\src\\ren01\\sample.csv"); File file = new File(path2); // 入力ストリームを生成。( FileNotFoundException が発生 ) FileInputStream input = new FileInputStream(file); /* 入力ストリームの読み込み。 ( UnsupportedEncodingException が発生 ) * ここでCSVファイルの文字コードを設定しないと文字化けします。 */ // 読み込むファイルの文字コード(SJIS) InputStreamReader stream = new InputStreamReader(input, "SJIS"); // バッファに取り込み。 // @SuppressWarnings("resource") BufferedReader buffer = new BufferedReader(stream); String line; int count = 0; /* readLine()でバッファの1行を取り出す作業を、読み込める行が無くなるまでwhile文で実行。 * line = buffer.readline() でBufferedReaderが保持する一行を取出しているので、ループする毎に書き変わります。 */ while((line = buffer.readLine()) != null) { // 取出した1行の文字セットを変換して新たに文字列を生成。 byte[] b = line.getBytes(); // String で UnsupportedEncodingException が発生 (変換したい文字コード:UTF-8) line = new String(b, "UTF-8"); // 文字列をカンマ区切りで配列に分けて要素ごとに出力。 // line.splitの第2引数に"-1"を指定しないと、他の行と要素数が // 違うため、出力結果の様にはなりません。 String[] columns = line.split(",", -1); // 読み込み行数カウント count++; Pattern p1 = Pattern.compile("^[0-9]+$"); // 内線番号 Pattern p2 = Pattern.compile("^[0-9]{3}-[0-9]{4}-[0-9]{4}$"); // 携帯番号 //Pattern p3 = Pattern.compile("^[a-zA-Z]{3}[0-9]{4}$"); //社員番号(英数字) // 英数字が1文字でも含まれていればOK(社員番号) Pattern p3 = Pattern.compile("^[^0-9]*$"); //社員番号(英数字) Pattern p4 = Pattern.compile("^[^\\d]+$"); // 簡単な正規表現(単純に数字が含まれていないというのを確認) for(int j = 0; j < columns.length; j++) { // System.out.println(j + " : " + columns[j]); //データ型チェック開始 if(j == 0 && p3.matcher(columns[j]).matches() == false) { System.out.println(count + "行目の" + "(A列)がおかしい: " + columns[j]); } else if(j == 1 && p4.matcher(columns[j]).matches() == false) { //if(j == 1 && p4.matcher(columns[j]).matches() == false) { System.out.println(count + "行目の" + "(B列)がおかしい: " + columns[j]); } else if(j == 2 && p1.matcher(columns[j]).matches() == false) { System.out.println(count + "行目の" + "(C列)がおかしい: " + columns[j]); } else if(j == 3 && p2.matcher(columns[j]).matches() == false) { System.out.println(count + "行目の" + "(D列)がおかしい: " + columns[j]); } //データ型チェック終了 } //System.out.println(""); } // 開いたストリームとバッファを閉じて関連するシステム・リソースを解放します。 ( IOException が発生 ) input.close(); stream.close(); buffer.close(); } catch (UnsupportedEncodingException | FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } =============================================
swordone

2016/06/15 07:12

横から失礼。 「英数字が一文字でもあればOK」というと、英数字以外の文字が混じっていてもOKになってしまいますがいいですか?
kumakumatan

2016/06/15 07:21

言葉足らずで申し訳ございません。 「英数字文字のみOK」です。 宜しくお願いします。
退会済みユーザー

退会済みユーザー

2016/06/15 08:25

Pattern.compile("^[0-9a-zA-Z]+$") //社員番号(英数字文字のみが1文字以上) - []の中: 文字範囲 - []の後が* : 0文字以上 - []の後が+ : 1文字以上 - []の後が{3} : 3文字 - []の後が{3,5} : 3~5文字 という意味です。
kaputaros

2016/06/16 00:29

横から失礼します。 String.matches()の性能は遅いんですね^^; 勉強になりました。ありがとうございます。
退会済みユーザー

退会済みユーザー

2016/06/19 01:03

String.matches()は内部で、PatternとMatherを使います。 したがって、1回だけのマッチングであれば、String.matches()でもオッケーです。 今回は何回もマッチングを行いますので、あらかじめPatternインスタンスを生成しておいたほうが性能が良いのです。
guest

0

「任意番号が整数型(int)かのチェック」については下記が参考になると思います。

あえて言うほどではない 数値変換時の型チェック Java編

それと「携帯番号に(-)が含まれている
かのチェック」については、単純に正規表現を使ったのではダメですか?

投稿2016/06/15 02:28

pi-chan

総合スコア5936

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

整数型かどうかを調べるならInteger#parseIntを使ってエラーかどうかで判断できます。

Java

1try { 2 Integer.parseInt(columns[2]); 3} 4catch(Exception e) { 5 // 整数に変換できない 6}

0~9の数字だけが使われているかは正規表現を使うことで調べることができます。

Java

1Pattern numPattern = Pattern.compile("^[0-9]+$"); 2Matcher m = numPattern.match(columns[2]); 3if(m.find()) { 4 // 数字だけ 5} 6else { 7 // 数字以外を含む 8} 9

「-」が使われているかどうかは単純にString#indexOfで調べるとよいでしょう。

Java

1if(columns[3].indexOf("-") == -1) { 2 // 含まない 3} 4else { 5 // 含む 6}

投稿2016/06/15 02:27

masaya_ohashi

総合スコア9206

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kaputaros

2016/06/15 02:42 編集

indexOf("-")だと、ループするか2回実行するかしないと "-"が1つしかない場合には対応しきれないですね。
masaya_ohashi

2016/06/15 02:45

1個見つかれば「含まれている」に該当するかなと省略してしまいました。確かに携帯番号のフォーマット通りかどうかをチェックするなら正規表現を使うべきでしょうね。
guest

0

String[] columns = line.split(",", -1);

で1カラムずつ値をとった後に、該当するインデクスの値をチェックすればいいと思います。

・任意番号が整数型(int)かのチェック
・携帯番号に(-)が含まれているかのチェック
java.lang.String#matches(String)
引数に正規表現を渡してあげればいいかと。

投稿2016/06/15 02:25

編集2016/06/15 02:26
kaputaros

総合スコア1844

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問