JavaScriptでString.Format的な超簡易テンプレート置換

// String.Format的な超簡易テンプレート置換関数
var Format = function(template, replacement)
{
    if (typeof replacement != "object") // 可変長引数時はreplacementを詰め替え
    {
        replacement = Array.prototype.slice.call(arguments, 1);
    }
    return template.replace(/\{(.+?)\}/g, function(m, c)
    {
        return (replacement[c] != null) ? replacement[c] : m
    });
}

// 例。可変長引数渡しでも配列渡しでもオブジェクト渡しでも可。
var case1 = Format("<div id={0}>{1}</div>", "あいでぃ", "要素");
var case2 = Format("<div id={0}>{1}</div>", ["あいでぃ", "要素"]);
var case3 = Format("<div id={ID}>{ELEM}</div>", { ID: "あいでぃ", ELEM: "要素" })

.NET FrameworkのString.Formatは文字を連結するのに、非常にお手軽で良いです。というわけでJavaScriptでもそれをやる。ついでにテンプレート置換風にオブジェクト渡しにも対応させる。単純な置換時は数字で、長ったらしい置換時はオブジェクトで。両方に対応させなければ、詰め替えが必要ないので正規表現でカカッと一行なんですねえ。詰め替えも別にslice.callで一発だし。以前にlinq.jsを絡めてgdgdとやってたのですが、二度もね!、あんなにgdgdやらずとも、もんのすごーく単純明快に書ける。無理やり使おうとして、無駄に複雑になるのはイクない。

と、恥ずかしくなったので今回載せました。あと、JavaScriptは文字連結面倒くせー、って時にササッとコピペで取り出して使いたい時のために(笑) ちゃんとDateTime等も含めたフォーマット変換に対応させるとか、テンプレートだったらちゃんとテンプレートエンジンな感じでforやifも動くように、とかの話は知りません。

そういえば、置換部分の関数ですけど、最初は格好つけて「return replacement[c] || m」って書いたんですが、これだとマッチがハッシュ内に見つからなかった場合(undefinedになってる)だけでなく、 空文字列の場合もfalse扱いになってしまってダメなんですね。C#の??のように使いたいのですが、例えば数字だと「var i = 0 || 3」だったら3になるしで使いづらい。というわけで、結局==nullばかり使うことになる。===undefinedって書けって話でもありますが、まあ、==nullのほうが色々考えなくて済むから楽で。

Profile

Yoshifumi Kawai

Cysharp, Inc
CEO/CTO

Microsoft MVP for Developer Technologies(C#)
April 2011
|
July 2023

Twitter:@neuecc GitHub:neuecc

Archive