【Java初心者用】メールアドレスをユーザ名とドメイン名に分割
Javaには文字列を処理するために様々なメソッドが用意されています。どのような時に利用できるのか、イマイチ使い方が分からない人も多いかも知れません。
そこで、今回は各種文字列処理用のメソッドを使って、メールアドレスをユーザ名とドメイン名に分割するプログラムの作り方について解説します。
何らかの処理をおこなうプログラムの正解は1つではありません。メールアドレスをユーザ名とドメイン名に分割する場合も色々なプログラムが存在します。初心者は色々なプログラムの書き方を参考にすると勉強になるので、この記事では3種類のプログラムを紹介します。
まず、この記事は以下のような人を対象としています。
対象者・Javaの勉強をしている初心者
・文字列処理用の各種メソッドの使い方を知りたい人
・メールアドレスをユーザ名とドメイン名に分割する方法を知りたい人
この記事を読むと、次のようなことが理解できるようになります。
この記事を読むとできること・メールアドレスをユーザ名とドメイン名に分割するプログラムの書き方を知ることができる
・indexOf()とlastIndexOf()の使い方を知ることできる
・substring()を使って一部の文字列を取り出す方法を知ることができる
・split()を使って文字列を分割する方法を知ることができる
・正規表現の使い方を知ることができる
入力されたメールアドレスをユーザ名とドメイン名に分割するプログラムを作ろうと考えています。どのように作れば良いでしょうか?
メールアドレスは文字列なので、各種文字列処理用のメソッドを利用すると分割することができますよ。
色々なメソッドがあって、どれを使えば良いのか迷ってしまいます。
色々なメソッドを使ってプログラムを作ることができます。
今回はサンプルプログラムとして3つ紹介します。
各種文字列処理用メソッド
プログラムを作成する場合、文字列を扱うことが頻繁にあります。例えば、ホームページで検索キーワードを入力し、Webサーバ側のプログラムで検索キーワードを分析したり、CSV形式のデータを分割し各種計算をおこなったり、様々な場面で文字列を操作しなければなりません。
JavaではStringクラス用意されていて、このクラスには文字列処理用のメソッドが多数定義されています。主なメソッドを取り上げると以下の表のようになります。
今回はこれらのメソッドのいくつかを使ってプログラムを作成します。
メールアドレスの分割
メールアドレスは一般的に使用できない文字がありますが、今回はプログラムを簡単にするためにどんな文字でも使用できるものとします。メールアドレスの書式は「文字列(1文字以上)@文字列(1文字以上)」とします。次のメールアドレスは不適切なものとして除外します。
- @が1文字もない (例:abcdefg)
- @が2文字以上ある (例:abc@def@ghi)
- @の前に何もない (例:@abc)
- @の前に空白のみある (例:□@abc) ※ □は空白
- @の後に何もない (例:abc@)
- @の後に空白のみある (例:abc@□) ※ □は空白
今回作成するプログラムのフローチャートは次の通りとします。
サンプル1:indexOf()、lastIndexOf()で判断する
まず最初のサンプルは「indexOf()」と「lastIndexOf()」を利用するプログラムです。
indexOf()とlastIndexOf()は()内で指定した文字列がどこに含まれているか調べ、見つかった場合はその位置を、見つからなかった場合はー1を返します。なお、位置の数え方は「0」から始まります。
indexOf()とlastIndexOf()の違いは、探す開始位置の違いです。indexOf()は1文字目から末尾に向かって検索するのに対して、lastIndexOf()は末尾から1文字目に向かって検索をします。なお、どちらも見つかった位置は先頭からの位置となります。
サンプルプログラムのコードは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
package mailaddress; import java.util.Scanner; public class MailAddress1 { public static void main(String[] args) { // メールアドレスの取得 String mail = getMailAddress(); // メールの書式が正しいかのチェック boolean isMail = isMailAddress(mail); // 正しい書式の場合 if (isMail) { // メールアドレスからユーザ名を取得 String userName = getUserName(mail); // メールアドレスからドメイン名を取得 String domainName = getDomainName(mail); // 結果の表示 showResult(mail, userName, domainName); // 間違った書式の場合 } else { // エラーメッセージの書式 showError(mail); } } public static String getMailAddress() { System.out.println("メールアドレスを入力してください"); // 入力された1行のデータを文字列として返す return new Scanner(System.in).nextLine(); } public static void showResult(String mail,String user,String domain) { System.out.println("\nメールアドレス:"+mail.strip()); System.out.println("ユーザ名:"+user); System.out.println("ドメイン名:" +domain); } public static void showError(String mail) { System.out.println("["+mail+"]\n正しい書式ではありません"); } public static boolean isMailAddress(String mail) { // 入力されたメールアドレスの前後の空白を除去 String temp = mail.strip(); int pos1 = temp.indexOf("@"); // 先頭からの@の位置 int pos2 = temp.lastIndexOf("@"); // 末尾からの@の位置 // @が含まれていない場合 if(pos1==-1) { return false; } // 先頭からと末尾からの位置が異なる場合(2個以上@がある) if(pos1!=pos2) { return false; } // @が最初の場合(@で始まっている) if(pos1==0) { return false; } // @が末尾の場合(@で終わっている) if(pos1==temp.length()-1) { return false; } return true; // 上記以外の場合は正しい書式 } public static String getUserName(String mail) { // @の位置を調べる int pos = mail.indexOf("@"); // 1文字目から@の位置までを取り出して返す // 前後に空白がある場合は除去する return mail.substring(0,pos).strip(); } public static String getDomainName(String mail) { // @の位置を調べる int pos = mail.indexOf("@"); // @の次の文字から末尾までを取り出して返す // 前後に空白がある場合は除去する return mail.substring(pos+1).strip(); } } |
サンプルプログラムの解説
まず、main()メソッド内は詳細なコードを記述せず、メソッドを記述し全体像を把握できるようにしてます。main()メソッド内の処理は上に示したフローチャートをそのままメソッドで記述しています。
なお、キーボードからメールアドレスを読み込むメソッド、結果を表示するメソッド、エラーメッセージを表示するメソッドの詳細については説明しません。各行のコメントを読んで確認して下さい。
メールアドレスの書式が正しいかどうかチェックするメソッド
52行目 String temp = mail.strip();
引数で受け取ったメールアドレス(変数mail)の前後に付けられているかもしれない空白(全角も含む)を取り除いています。なお、空白を取り除くメソッドとして「trim()」メソッドもありますが、こちらは全角空白は取り除いてくれません。もし、空白が前後になければ何も処理されません。
54行目 int pos1 = temp.indexOf(“@”);
55行目 int pos2 = temp.lastIndexOf(“@”);
54行目は「@」の位置を先頭から調べ、存在していれば最初の@の位置を返します。複数@が存在していても返すのは最初に見つかった@の位置だけです。55行目は@の位置を末尾から調べ、存在していれば最初の@の位置を返します。こちらも複数@が存在していても返すのは最初に見つかった@の位置だけです。なお、どちらのメソッドも@の位置は「1文字目(0)から数えた位置」となります。
58行目 if(pos1 == -1) { return false; }
indexOf()メソッドの実行結果が「-1」の場合は()内で指定した文字列(@)が含まれていないことを示します。「メールアドレスは1個の@を含む」という条件に合致しないため、不適切な書式となります。この場合、falseを返します。
61行目 if(pos1 != pos2 ) { return false; }
文字列の先頭と末尾から@の位置をそれぞれ求め、その値を比較すると@の数を調べることができます。もし、@が1つしかない場合はこの2つの値は一致します。一方、@が2つ以上あるとこの2つの値は一致しません。したがって、2つの値が一致しない場合は不適切な書式なのでfalseを返します。
64行目 if(pos1 == 0) { return false; }
indexOf()メソッドの結果が「0」の場合、1文字目に@があり、その前(ユーザ名の部分)には何もないことになります。ユーザ名がないので不適切な書式となり、falseを返します。
67行目 if(pos1 == temp.length-1 ) { return false; }
indexOf()メソッドの結果が末尾かどうかをチェックしています。末尾の場合、位置は文字数-1となります。@が末尾にあるということは、ドメイン名がないということなので不適切な書式となります。したがって、falseを返します。
69行目 return true;
上記のすべての条件と一致しない場合は正しい書式なので、trueを返します。
メールアドレスからユーザ名のみを取り出すメソッド
引数で受け取ったメールアドレスからユーザ名を取り出して返すメソッドにつてい解説します。
74行目 int pos = mail.indexOf(“@”);
ユーザ名はメールアドレスのうち、@より前半部分となります。まずは@の位置を調べます。
78行目 return mail.substring(0,pos).strip();
substring()メソッドは文字列の一部分だけを取り出すメソッドです。第1引数には取り出す最初の文字の位置、第2引数は取り出す最後の文字の位置-1をそれぞれ指定します。第2引数に指定した位置の文字は取り出されないので注意してください。前後に空白が含まれている場合は除去します。
メールアドレスからドメイン名のみを取り出すメソッド
引数で受け取ったメールアドレスからドメイン名を取り出して返すメソッドについて解説します。
84行目 int pos = mail.indexOf(“@”);
ドメイン名はメールアドレスのうち、@より後半部分となります。まずは@の位置を調べます。
88行目 mail.substring(pos+1).strip();
ユーザ名と同様にsubstring()メソッドを使って、メールアドレスからドメイン名だけを取り出します。substring()メソッドに引数を1つだけ指定した場合は、その位置から末尾までが対象となります。
取り出すドメイン名は「@の次の文字から」となるので、引数には「pos+1」を指定します。前後に空白が含まれている場合は除去します。
サンプル2:split()で判断する
2つ目のサンプルは@の位置や数をsplit()メソッドを使ってチェックするものです。@を区切り文字としてメールアドレスを分割し、要素数を調べることによって@の個数を調べられます。
サンプルプログラムのコードは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
package mailaddress; import java.util.Scanner; public class MailAddress2 { public static void main(String[] args) { // メールアドレスの取得 String mail = getMailAddress(); // メールの書式が正しいかのチェック boolean isMail = isMailAddress(mail); // 正しい書式の場合 if (isMail) { // メールアドレスからユーザ名を取得 String userName = getUserName(mail); // メールアドレスからドメイン名を取得 String domainName = getDomainName(mail); // 結果の表示 showResult(mail, userName, domainName); // 間違った書式の場合 } else { // エラーメッセージの書式 showError(mail); } } public static String getMailAddress() { System.out.println("メールアドレスを入力してください"); // 入力された1行のデータを文字列として返す return new Scanner(System.in).nextLine(); } public static void showResult(String mail,String user,String domain) { System.out.println("\nメールアドレス:"+mail.strip()); System.out.println("ユーザ名:"+user); System.out.println("ドメイン名:" +domain); } public static void showError(String mail) { System.out.println("["+mail+"]\n正しい書式ではありません"); } public static boolean isMailAddress(String mail) { // 入力されたメールアドレスの前後の空白を除去 String temp=mail.strip(); // メールアドレスを@で分割 String[] array = temp.split("@"); // 要素数が2で最初のデータがnull以外の場合 if(array.length==2 && !array[0].equals("")) { return true; // 正しい書式なのでtrueを返す }else { // それ以外の場合 return false; // 不適切な書式なのでfalseを返す } } public static String getUserName(String mail) { // メールアドレスを@で分割 String[] mailArray = mail.split("@"); // 最初の要素のデータを前後の空白を除去して返す return mailArray[0].strip(); } public static String getDomainName(String mail) { // メールアドレスを@で分割 String[] mailArray = mail.split("@"); // 2つ目の要素のデータを前後の空白を除去して返す return mailArray[1].strip(); } } |
サンプルプログラムの解説
このサンプルではサンプル1とほとんど内容は同じです。異なる部分は、書式のチェックとユーザ名の取得、ドメイン名の取得です。
メールアドレスの書式が正しいかどうかのチェックするメソッド
52行目 String temp = mail.strip();
まず、入力されたメールアドレスの前後に存在する空白文字を除去します。
55行目 String[ ] array = temp.split(“@”);
メールアドレス(文字列)をsplit()メソッドを使って「@」を区切り文字として分割し、分割された文字列を配列に代入します。
58行目 if(array.length == 2 && !array[0].equals(“”) ) {
この行で@が1つで、空白で始まっていない(ユーザ名がない)かを判断しています。
下の図で正しい書式と不適切な書式の場合にどのような状態になっているのかを確認して下さい。
正しい書式の場合は、「要素数が2でなおかつ先頭の要素が空文字(“”)でない」ことが条件となることが判断できます。
メールアドレスからユーザ名のみを取り出すメソッド
67行目 String[ ] mailArray = mail.split(“@”);
正しい書式の場合、メールアドレスを「@」で分割し、それぞれのデータを配列に格納します。
70行目 return mailArray[0].sprit();
ユーザ名は分割されたデータのうち、添え字「0」の要素に格納されているので、そのデータを返します。なお、前後に空白が含まれている場合は除去します。
メールアドレスからドメイン名のみを取り出すメソッド
75行目 String[ ] mailArray = mail.split(“@”);
正しい書式の場合、メールアドレスを「@」で分割し、それぞれのデータを配列に格納します。
78行目 return mailArray[1].sprit();
ドメイン名は分割されたデータのうち、添え字「1」の要素に格納されているので、そのデータを返します。なお、前後に空白が含まれている場合は除去します。
サンプル3:正規表現で判断する
最後のサンプルは少し高度なプログラムとなります。正規表現は、あるデータが特定の書式と一致するかどうかをチェックする際にif文などを複数使わず簡単に処理できるものです。非常に便利なので、プログラマは是非正規表現の使い方を覚えておいた方が良いでしょう。
サンプルプログラムのコードは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
package mailaddress; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public class MailAddress3 { public static void main(String[] args) { // メールアドレスの取得 String mail = getMailAddress(); // メールの書式が正しいかのチェック boolean isMail = isMailAddress(mail); // 正しい書式の場合 if (isMail) { // メールアドレスからユーザ名を取得 String userName = getUserName(mail); // メールアドレスからドメイン名を取得 String domainName = getDomainName(mail); // 結果の表示 showResult(mail, userName, domainName); // 間違った書式の場合 } else { // エラーメッセージの書式 showError(mail); } } public static String getMailAddress() { System.out.println("メールアドレスを入力してください"); // 入力された1行のデータを文字列として返す return new Scanner(System.in).nextLine(); } public static void showResult(String mail,String user,String domain) { System.out.println("\nメールアドレス:"+mail.strip()); System.out.println("ユーザ名:"+user); System.out.println("ドメイン名:" +domain); } public static void showError(String mail) { System.out.println("["+mail+"]\n正しい書式ではありません"); } public static boolean isMailAddress(String mail) { // 前後の空白文字の除去 String temp=mail.strip(); // メールアドレスの書式を示す文字列 String regex = "^[^@]{1,}@[^@]{1,}[^@]$"; // Patternオブジェクトの生成 Pattern p = Pattern.compile(regex); // 書式オブジェクトに受取ったメールアドレスを適用 Matcher m = p.matcher(temp); // 一致するかどうか(true/false)を返す return m.matches(); } public static String getUserName(String mail) { // メールアドレスを@で分割 String[] mailArray = mail.split("@"); // 最初の要素のデータを前後の空白を除去して返す return mailArray[0].strip(); } public static String getDomainName(String mail) { // メールアドレスを@で分割 String[] mailArray = mail.split("@"); // 2つ目の要素のデータを前後の空白を除去して返す return mailArray[1].strip(); } } |
正規表現
正規表現は、あるデータがが指定した書式と等しいかを詳細にチェックすることできる機能で、多くのプログラム言語で利用できます。
例えば、郵便番号は「数字3桁-数字4桁」と書式が決まっています。入力されたデータが郵便番号かどうかをチェックする場合、if文や文字列処理用のメソッドを駆使しなければならず、手間が非常にかかってしまいます。しかし、正規表現を利用すれば簡単に、更により細かなチェックをおこなうことができます。
正規表現を利用する場合、書式の指定が重要となります。あらかじめ用意されている記号などを利用して書式を指定するのですが、初心者はまず、書式の書き方を覚える必要があります。
代表的な記号は以下の通りです。
サンプルプログラムの解説
このサンプルでは、split()メソッドを使ったサンプルプログラムと比較すると、メールアドレスの書式が正しいかを判定するisMailAddress()メソッドのみ異なっています。したがって、このメソッド部分のみ解説します。
メールアドレスの書式が正しいかどうかのチェックするメソッド
54行目 String temp = mail.strip();
まず、入力されたメールアドレスの前後に存在する空白文字を除去します。
57行目 String regex = “^[^@]{1,}@[^@]{1,}[^@]$”;
メールアドレスの書式を文字列で記述します。ユーザ名部分は「^[^@]{1,}」で書式を表現しています
- ^ これは行頭、つまり最初の1文字を意味します
- [^@] [ ]はこの中のどれか1文字を意味しますが、[ ]内に「^」があると、[]内以外の1文字となります
- {1,} {}は直前の文字の繰り返しを意味し、繰り返す回数は{}内で指定します。{}内が「1,」となっているので、「1文字以上何文字でも構わない」となります。
つまり、ユーザ名部分は「1文字目が@以外で、2文字以降は@以外で何文字でもOK」となります。
途中の「@」は@文字そのものを表します。
ドメイン名部分もユーザ名部分とほぼ同じです。「[^@]{1,}$」の書式は「@以外の文字が1文字以上連続し、最後の文字が@以外で終わる」ことを表現しています。なお、最後の「$」は行末を意味しています。
60行目 Pattern p = Pattern.conpile(regex);
正規表現の書式は57行目で文字列として指定しているだけなので、この文字列から表記表現を扱うためのオブジェクトを作成する必要があります。
63行目 Matcher m = p.matcher(temp);
正規表現のオブジェクトを生成したら、チェックしたいデータに正規表現を適用します。これで、各種正規表現用に用意されているメソッドが使えるようになります。
66行目 return m.matches();
正規表現は、完全に一致するか、部分的に一致するかのチェックをおこなうことができます。このmatches()メソッドは完全に指定した正規表現の書式と一致するかどうかを判定します。完全に一致する時にtrueを返します。なお、部分的に一致するかどうかをチェックしたい場合はfind()メソッドを利用します。
まとめ
今回は、メールアドレスをユーザ名とドメイン名に分割するプログラムについて説明しました。
1つのサンプルプログラムだけではなく、今回は3つサンプルプログラムを紹介しています。どれでも同じ結果を得ることができるので、どれもプログラムとしては正解です。
プログラムの勉強を始めた初心者は1つのプログラムをインターネットで見つけても、他にプログラム(解き方)がないのか是非探してみて下さい。このサイトで何度も話していますが、プログラムのスキルアップには同じ問題でも色々なプログラムの書き方を見聞きすることが非常に大切です。
見たことのないプログラムはなかなか自分では作成することができません。色々なサンプルプログラムは自分の財産になります。
・文字列操作用のメソッドは多数用意されている
・プログラムでは文字列を扱う場面が多いのでこれらのメソッドの使い方を覚えることは重要
・正規表現を使うと詳細な書式の設定がおこなえる
サンプルプログラムはいかがでしたか?
自分で理解しやすいものは見つかりましたか?
同じことをするのに、色々な解き方があるんですね。
1つのサンプルだけにこだわらず、色々な書き方にチャレンジしてみて下さい!!
見慣れていると、様々な場面でのアイデアとして活用できますよ。