検索

キーワード


【Java】文字列の置き換え(MessageFormat)!日付や数値をフォーマットするやり方解説!

  • 公開日:2020-08-07 16:58:43
  • 最終更新日:2021-01-25 10:59:25
【Java】文字列の置き換え(MessageFormat)!日付や数値をフォーマットするやり方解説!

こんにちは。新人エンジニアのサトウです。

システムエンジニアとして駆け出したばかりですが、

初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。


プログラム初心者✅にも、プログラムに興味がある人✨も、

短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!

【java.textパッケージ】MessageFormatクラス

MessageFormatは、連結されたメッセージを、言語に依存しない方法で構築するためのクラスです。

文字列の一部を外部から渡される値(パラメータ)で置き換える時に使用できます。

Javaではreplaceメソッドや正規表現で置換の操作を行うこともできますが、

エラーメッセージや日付時刻など、定形文字列の一部を置き換えたい場合は、MessageFormatクラスを使うと便利です。

このクラスでは引数に Object型を使用することができます。

Object型は全てのデータ型に対する基底のデータ型(クラス型変数)でObjectクラスのオブジェクトです。


今回は以下のMessegeFormatクラスを利用した文字列置換を紹介します。


staticメソッドを使ってフォーマットする方法

インスタンスを生成してからフォーマットする方法

数値または日時のフォーマットを指定する方法


MessageFormatクラスはjava.textパッケージの中に存在しているため、

使用の際はjava.text.MessageFormatをインポートする必要があります。


Stringクラスのreplaceメソッドに関しては以下のリンク先記事で紹介しています。

参考:【Java】Stringクラスについての理解と基本的な文字列操作

staticメソッドを使ってフォーマットする方法

staticメソッドを使うやり方では、formatメソッドが呼ばれたときに

内部的には一回限りの目的でMessageFormat インスタンスを生成します。

後でパラメータを操作できないので注意しましょう。


MessageFormatクラスのformatメソッドは第一引数にフォーマットの文字列を指定します。

このフォーマット文字列には、【{0},{1},{2}...】のArgumentIndex(引数インデックス)を含めます。

ArgumentIndex(引数インデックス)は文字列の一部を外部から渡される値(パラメータ)の置換対象です。

文字列の例:

"エラーメッセージ:{0} 個数は{1}個以上にしてください。"
"{0}件のエラーを確認しました。{1}を書き直してください。{2}を半角英数字で入力してください。"
"Aグループは{0}人、Bグループは{1}人、Cグループは{2}人です。"


ここでは基本的な操作方法として下記の2つを紹介します。


第二引数にObject配列を指定するやり方(formatメソッド)

第二引数以降にArgumentIndex(引数インデックス)分のオブジェクトを指定するやり方(formatメソッド)



Stringクラスのformatメソッドについては下記のリンク先記事で紹介しています。

参考:【Java】Stringクラスformatメソッドの文字列整形とエスケープシーケンス


- 第二引数にObject配列を指定するやり方/formatメソッド

String format(String ,Object配列)

Object配列の要素には、型にとらわれず要素を指定することができます。

import java.text.MessageFormat;

public class Test {
	public static void main(String[] args) {

		Object[] o = { "数十", 127,12345};

		String s = MessageFormat.format(
				"Aグループは{0}人、Bグループは{1}人、Cグループは{2}人です。",
				o);

		System.out.println(s);
	}
}

出力すると以下のようになります。

Aグループは数十人、Bグループは127人、Cグループは12,345人です。



- 第二引数以降にArgumentIndex(引数インデックス)分のオブジェクトを指定するやり方/formatメソッド

String format(String ,ArgumentIndex(引数インデックス)分のオブジェクト...)

第二引数以降にArgumentIndex(引数インデックス)分のオブジェクトを指定します。

どんな指定することができます。


第二引数に指定されたオブジェクトが、ArgumentIndexの{0}に割り当たります。

以降追加されるごとに、インデックスのように値が+1され、そのオブジェクトへ割り振られていきます。

ArgumentIndex(引数インデックス)分以上を指定すると例外が発生します。

import java.text.MessageFormat;

public class Test {
	public static void main(String[] args) {

		String x ="数十";
		byte   y =127;
		int    z =12345;

		String s = MessageFormat.format(
				"Aグループは{0}人、Bグループは{1}人、Cグループは{2}人です。",
				x,y,z);

		System.out.println(s);
	}
}

出力すると以下のようになります。

Aグループは数十人、Bグループは127人、Cグループは12,345人です。



インスタンスを生成してからフォーマットする方法

インスタンスの生成時にフォーマットの文字列を引数に取ります。

同じフォーマット(テンプレート)に対して様々なパラメータで置換をすることができます。

ループ処理などで、同じフォーマットに対して複数回処理する場合に、毎回パターンを定義する必要がないため、

staticメソッドのformat()を使った場合より高速になります。


- 初期化(インスタンス化)と String値への変換/toPatternメソッド

MessageFormat messageformat = new MessageFormat(文字列);

【{0},{1},{2}...】のArgumentIndex(引数インデックス)を含むフォーマットの文字列を指定します。


MessageFormatに現在設定されているパターン文字列を取得するには、MassegeFormatクラスのtoPatternメソッドを使用します。

String toPattern()

以下の例で実際に初期化を行っているところを確認しましょう。

import java.text.MessageFormat;

public class Test {
	public static void main(String[] args) {

		//初期化
		MessageFormat mf = new MessageFormat(
                        "Aグループは{0}人、Bグループは{1}人、Cグループは{2}人です。");		

		//String値へ変換
		String s= mf.toPattern();

		System.out.println(s);
	}

出力すると以下の様になります。

Aグループは{0}人、Bグループは{1}人、Cグループは{2}人です。

これで初期化は完了です。


- 要素の置き換え/formatメソッド

初期化した文字列の一部をパラメータへ置き換えましょう。 

String format(クラス型の配列)

引数には、String[]やObject[]などのクラス型配列を使います。

インスタンス化して使う方法のformatメソッドはjava.text.Formatクラスから継承したメソッドです。


intやlongなどの基本データ型を代入したい際は、ラッパーしたクラス型を使います。下の表を見てください。

ラップしたクラス型とは「型」に加工処理機能(メソッドなど)を持たせるためにクラス化させた型を指します。

クラス化のルールに従って型の先頭文字は大文字で表記されます。また本来の名前で表記されます。

ラッパークラス表

以下の例で実際に要素の置き換えをしてみましょう。

import java.text.MessageFormat;

public class Test {
	public static void main(String[] args) {

		MessageFormat mf = new MessageFormat(
                        "Aグループは{0}人、Bグループは{1}人、Cグループは{2}人です。");

		Integer[] i = { 50, 20, 40 };
		String[] s = { "日本", "イギリス", "オーストラリア" };
		Object[] o = { "数十",127, 12345 };

		System.out.println(mf.format(i));
		System.out.println(mf.format(s));
		System.out.println(mf.format(o));
	}
}

出力すると以下のようになります。

Aグループは50人、Bグループは20人、Cグループは40人です。
Aグループは日本人、Bグループはイギリス人、Cグループはオーストラリア人です。
Aグループは数十人、Bグループは127人、Cグループは12,345人です。




数値または日時のフォーマットを指定する方法

- 数値フォーマットの操作

MessegeFormatクラスは、数字にフォーマットの指定をして表示することができます。

【{0},{1},{2}...】のArgumentIndex(引数インデックス)に フォーマットのスタイルを追加することで表示可能です。


デフォルトの数値フォーマットは、千桁ごとにカンマが入るようになっています。

以下のような書き方でフォーマットを変更できます。

カンマなしの表示:{ArgumentIndex,number,#}
ゼロ埋め(パディング)の表示:{ArgumentIndex,number,00000}


使用例を見てみましょう。

import java.text.MessageFormat;

public class Test {
	public static void main(String[] args) {

        //Object配列
		Object[] o = { 1234,1234,1234};

		String s = MessageFormat.format(
				"Aグループは{0}人、"
				+ "Bグループは{1,number,#}人、"
				+ "Cグループは{2,number,00000000}人です。",o);

		System.out.println(s);
	}
}

出力すると以下のようになります。

Aグループは1,234人、Bグループは1234人、Cグループは00001234人です。



- 日付時刻フォーマットの操作

MessegeFormatクラスではフォーマットへ日付時刻を置換することが可能です。


Dateクラス・Calendarクラスを使った日付時刻取得(旧API)での置換

java.timeパッケージを利用した日付時刻取得 (Date And Time API-Java8)での置換


をみていきましょう。


日付時刻の取得について詳しくは以下の記事で紹介しています。

APIについて理解が不十分の方はこちらで理解を深めましょう。

参考:【Java】日付取得(新API-Java8)

   【Java】日付時刻(新API‐Java8) - 日時比較・日時演算

   【Java】日付時刻(新API‐Java8) - フォーマット

   【Java】日付時刻(新旧 API 相互変換)

   【Java】日時取得(従来API)-java.util.Date, java.util.Calendar

   【Java】日付時刻(従来のAPI) - 操作(計算、比較、フォーマット)

   【Java】日付時刻のまとめ


Dateクラス・Calendarクラスを使った日付時刻取得(旧API)での置換

Dateクラスのインスタンスを生成して日付時刻を表示させます。

【{0},{1},{2}...】のArgumentIndex(引数インデックス)に【date/time】を追加することで日時を個々に表示可能です。

また、フォーマットのスタイルを追加することで以下のように任意のフォーマットが指定できます。

date/フォーマットの表示:{ArgumentIndex,date,yyyy年MM月dd日}
time/フォーマットの表示:{ArgumentIndex,time,HH時mm分ss秒}

詳しいフォーマットの指定記述は、

【Java】日付時刻(従来のAPI) - 操作(計算、比較、フォーマット)の記事を参考にしてください。


①【staticメソッドを使ってフォーマットする方法】での表示
import java.text.MessageFormat;
import java.util.Date;

public class Test {
	public static void main(String[] args) {

		Date d = new Date();

		String s = MessageFormat.format(
				"本日は{0}です。"
				+ "日付:{0,date}と"
				+ "時刻:{0,time}を分けて表示も可能です。",d);

		String t =MessageFormat.format(
				"日付:{0,date,yyyy年MM月dd日}と"
				+ "時刻:{0,time,HH時mm分ss秒}でフォーマット表示も可能です。",d);

		System.out.println(s);
		System.out.println(t);
	}
}

出力すると以下のようになります。

本日は2020/08/06 18:52です。日付:2020/08/06と時刻:18:52:11を分けて表示も可能です。
日付:2020年08月06日と時刻:18時52分11秒でフォーマット表示も可能です。


②【インスタンスを生成してからフォーマットする方法】での表示
import java.text.MessageFormat;
import java.util.Date;

public class Test {
	public static void main(String[] args) {

		MessageFormat mf = new MessageFormat("本日は{0}です。");
		MessageFormat mf2= new MessageFormat("日付は{0,date}です。");
		MessageFormat mf3= new MessageFormat("時刻は{0,time}です。");

		Object[] d = {new Date()};

		System.out.println(mf.format(d));
		System.out.println(mf2.format(d));
		System.out.println(mf3.format(d));
	}
}

出力すると以下のようになります。

本日は2020/08/06 12:04です。
日付は2020/08/06です。
時刻は12:04:51です。

ここでの表示においても【{0},{1},{2}...】のArgumentIndex(引数インデックス)に

フォーマットのスタイルを追加することで①と同じように任意のフォーマットが指定できます。


java.timeパッケージを利用した日付時刻取得 (Date And Time API-Java8)での置換

①【staticメソッドを使ってフォーマットする方法】での表示
import java.text.MessageFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class Test {
    public static void main(String[] args) {

        String s = MessageFormat.format(
		         "本日は{0}です。"
		         + "日付:{1}は時刻:{2}を分けて表示も可能です。",
				 LocalDateTime.now(),
				 LocalDate.now(),
				 LocalTime.now()
                 );

        System.out.println(s);
	}
}

出力すると以下のようになります。

本日は2020-08-06T12:58:59.041935100です。日付:2020-08-06は時刻:12:58:59.042934300を分けて表示も可能です。


※java.timeパッケージを利用した日付時刻取得では日時のフォーマットを操作してから置換することもできます。

詳しいフォーマットの指定記述は、【Java】日付時刻(新API) - 操作(計算、比較、フォーマット)を参考にしてください。


import java.text.MessageFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

public class Test {
	public static void main(String[] args) {

		//インスタンス生成
		LocalDateTime localDateTime = LocalDateTime.now();
		LocalDate localDate = LocalDate.now();
		LocalTime localTime = LocalTime.now();

		//フォーマット操作
		DateTimeFormatter datetime = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH時mm分ss秒");
		DateTimeFormatter date = DateTimeFormatter.ofPattern("yyyy-MM-dd");
		DateTimeFormatter time = DateTimeFormatter.ofPattern("HH:mm:ss:SS");

		//置換
        String s = MessageFormat.format(
				 "本日は{0}です。"
				 + "日付:{1}は時刻:{2}を分けて表示も可能です。",
				 localDateTime.format(datetime),
				 localDate.format(date),
				 localTime.format(time)
                 );

		System.out.println(s);
	}
}

出力すると以下のようになります。

本日は2020年08月06日 13時12分20秒です。日付:2020-08-06は時刻:13:12:20:71を分けて表示も可能です。


②【インスタンスを生成してからフォーマットする方法】での表示
import java.text.MessageFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class Test {
	public static void main(String[] args) {

		MessageFormat mf = new MessageFormat("本日は{0}です。");
		MessageFormat mf2= new MessageFormat("日付は{0}です。");
		MessageFormat mf3= new MessageFormat("時刻は{0}です。");

		Object[] dt= {LocalDateTime.now()};
		Object[] d = {LocalDate.now()};
		Object[] t = {LocalTime.now()};

		System.out.println(mf.format(dt));
		System.out.println(mf2.format(d));
		System.out.println(mf3.format(t));
	}
}

出力すると以下のようになります。

本日は2020-08-06T13:17:03.757747400です。
日付は2020-08-06です。
時刻は13:17:03.757747400です。


※①と同様に日時のフォーマットを操作してから置換することもできます。


【著者】

新人SE・サトウ

読者を始め私自身も知りたい!と思うような知って得するプログラミング知識やIT情報を日々発信中です。
筆者の憧れの人物は、コリン・ファースさん、渡部篤郎さん。
教養のあるカッコいい大人になれるよう、プログラミングを始め興味関心を持ったことを毎日勉強しております !!

よく読まれている記事
【Java】JSPでタグライブラリを使う(JSTL)

【Java】JSPでタグライブラリを使う(JSTL)

こんにちは。エンジニアの新田です!ここでは、システムエンジニアとして働いている私が、システム開発手法や開発言語について紹介していこうと思います。今回は、JSPの標準タグライブラリ「JSTL」について紹介します。Javaについて勉強している方、Webアプリケーションを構築したいと思っている方の参考になれば幸いです!関連記事リンク: 【Java】JSPの基本的な構文/【Java】JSPのアクションタグ

【Java】Stringクラス文字列を操作するメソッドの使い方まとめ!実例も紹介!

【Java】Stringクラス文字列を操作するメソッドの使い方まとめ!実例も紹介!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!そもそもStringとは何?『 String 』... Java言語において文字列のデータ型を指します。基本デ

【Java】文字列の置き換え(String#format)!エスケープシーケンスのまとめも!!

【Java】文字列の置き換え(String#format)!エスケープシーケンスのまとめも!!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!Stringクラスformatメソッドの文字列整形【java.utilパッケージ】Formatterクラスfo

【Java】文字列格納後に変更可能!?StringBufferクラスとStringBuilderクラス!

【Java】文字列格納後に変更可能!?StringBufferクラスとStringBuilderクラス!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者にも✅、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!文字列を扱う3つのクラス【java.langパッケージ】java.langパッケージの文字列を扱うクラスにはS

【Java】値?変数?型??しっかり解説!『データ型(プリミティブ型と参照型)』

【Java】値?変数?型??しっかり解説!『データ型(プリミティブ型と参照型)』

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!プリミティブ型と参照型プログラム開発では型を持った変数を使ってデータのやり取りをしますが、データ型によって仕様