今回はMaxScriptで利用できる文字列整形の方法をまとめてみました。
加算演算を使ったシンプルな結合
i = 25
s = "Test1"
"Values: (" + s + ", " + (i as string) + ")"
--> "Values: (Test1, 25)"
基本的にこれだけで問題無い事も多いのですが、文字列以外はあらかじめas演算子で変換する必要があるのと、+や””が大量に必要になるため、データ数が増えてくると使い勝手がかなり悪くなります。また、複雑な書式を指定した数値の整形は出来ません。
formatを使った整形
次によく使われる方法として、標準関数のformatがあります。formatはtoオプションを指定する事によって、出力先をStringStreamに変更する事が出来ます。
ただし、そのままでは文字列として利用出来ないので、最終的にはstringに変換してやる必要があります。
また、プレースホルダとして % 記号を使用出来ます。文字列にプレースホルダが含まれる場合、第二引数以降のデータが文字列に埋め込まれます。
ss = StringStream ""
format "Values: (%, %)" "Test2" 36 to:ss
ss as string
--> "Values: (Test2, 36)"
StringStreamは高速な文字列ストリームとして動作するので、速度が必要とされる長文の整形などに向いています。
FormattedPrint
標準関数のformattedPrintは、数値を書式付きで文字列に変換する関数です。例えば数値の左右揃え、空白や桁数の指定、0(ゼロ)詰めなど、数値整形において必要な機能が一通りそろっています。
ただし、この関数はあくまでも数値を文字列に変換する関数であり、文字列そのものを整形する関数ではありません。
その場合、formatと組み合わせて使ってやる必要があります。
-- 5桁で0詰めして整数出力
formattedPrint 987 format:"05d"
--> "00987"
-- 文字数10文字(記号含む)、小数部5桁で浮動小数出力
formattedPrint pi format:"10.5f"
--> " 3.14159"
-- 0詰めと組み合わせ
formattedPrint pi format:"010.5f"
--> "00003.1416"
DotNetのString.Format
最後に、.NET FrameworkのString.Formatを使用する方法を紹介します。
String.Formatは、formattedPrintより複雑な書式指定子を利用する事ができ、かつformatのようにデータの埋め込みを容易に行う事が出来ます。
ただし、Maxのバージョンによって引数の扱いが多少異なり、バージョンによって結果が変わってしまう事があるので注意が必要です。
String.Formatでは、{0}, {1}という風に、大括弧+引数の番号でプレースホルダを指定します。MaxScriptとは違い引数の連番が0から始まるので注意が必要です。更に、引数番号の後に : (コロン) を続けて、詳細な書式指定を行う事が出来ます。
strCls = dotNetClass "System.String"
-- シンプルなデータの埋め込み
strCls.Format "Values: ({0}, {1})" "HogeHoge" 48
--> "Values: (HogeHoge, 48)"
-- 浮動小数 有効桁数4桁で出力
strCls.Format "{0:F4}" pi
--> "3.1415"
-- 整数を0(ゼロ)詰めで出力
strCls.Format "{0:000}" 4
--> "004"
その他にもありとあらゆる整形指示を行う事が出来ますが、ここで詳しく説明すると切りが無いので、関数の紹介程度に止めておきます。
詳細に関しては、ググると細かく説明しているサイトが沢山見つかります。
リファレンス: 標準の数値書式指定文字列
リファレンス: カスタム数値書式指定文字列
smdn様: 書式指定子
@IT様: 数値を右詰めや0埋めで文字列化するには?
4つ以上の引数を指定する
MaxScriptでString.Formatを使う際の注意点として、4つ以上のデータを引数として渡そうとすると、ランタイムエラーが発生してしまう問題があります。
(dotNetClass "System.String").Format "{0}, {1}, {2}, {3}" 1 2 3 4
--> ランタイム エラー: No method found which matched argument list
そういった場合、引数を配列としてまとめて渡してやる事が可能です。
(dotNetClass "System.String").Format "{0}, {1}, {2}, {3}" #(10, 20, "Foo", "Bar")
--> "10, 20, Foo, Bar"
17/11/25 追記
Max2014までは上記の方法で引数を渡せたのですが、2015(16?)から直接配列が渡せなくなってしまいました。
(dotNetClass "System.String").Format "{0}, {1}, {2}, {3}" #(10, 20, "Foo", "Bar")
--> ランタイム エラー: dotNet runtime exception
対応策として、Maxの配列をあらかじめ.NETのObject型配列に変換してやります。
毎度書くと面倒なので、下記のようなユーティリティ関数を用意してやると便利です。
fn stringFormat pattern args =
(
type = dotNetClass "System.Object[]"
args = dotnet.ValueToDotNetObject args type
(dotNetClass "System.String").Format pattern args
)
stringFormat "{0}, {1}, {2}, {3}" #(10, 20, "Foo", "Bar")
--> "10, 20, Foo, Bar"
18/08/26追記
Max2016 SP4にて、上記の問題は解決されたみたいです。
逆に、Object型配列への変換がエラーになってしまうみたいなので、バージョンにより動作を変更する仕組みが必要かもしれません。
もしくは、引数の数が4つ以上の時は、諦めてformatを使うほうがいいかもしれませんね。