0

私は数日前に単純なテンプレート関数を書きましたが、今の問題は、空白がタグを殺すことです。したがって、次のように入力する<div id="str">#{my} #{name} #{is} #{#{a}}</div>と、うまく機能しますが、次のようには機能しません<div id="str">#{my} #{name} #{is} #{ #{a} }</div>

これまでに行ったことは次のとおりです。

$.tmpl = function(str, obj) {
    do {
        var beforeReplace = str;
        for(var key in obj) {
            str = str.replace("#{" + key + "}", obj[key]);
        }
        var afterReplace = str !== beforeReplace;
    } while (afterReplace);

    return str;
};


var map = {
    my: "Am",
    name: "I",
    is: "<a href='#'>awesome</a>",
    a: "#{b}",
    b: "c",
    c: "?"
};

$("#str").html(function(index, oldhtml) {
    $(this).html( $.tmpl(oldhtml, map) );
});

#{a}とを使用する場合、どのように機能させることができますか#{ #{a} }。私はそれが可能であり、単純でさえあることを知っていますが、私は正規表現のプロではありません。

これは機能します。

これは失敗します

4

2 に答える 2

4

置き換えるキーから空白を削除する必要があります。これを行うには、String.replace() 関数の 2 番目のパラメーターとして関数を使用できます。このような関数を使用して、各パスのすべての一致を一度に置き換えることもできます。したがって、次のことを試してください。

$.tmpl = function(str, obj) {
    do {
        var beforeReplace = str;
        str = str.replace(/#{([^}]+)}/g, function(wholeMatch, key) {
            var substitution = obj[$.trim(key)];
            return (substitution === undefined ? wholeMatch : substitution);
        });
        var afterReplace = str !== beforeReplace;
    } while (afterReplace);

    return str;
};

正規表現 /#{([^}]+)}/g は、"#{" で始まり、a 以外の文字が少なくとも 1 つある文字列のすべての出現箇所 ("g" は "グローバル" を意味します) を検索します。 "}" の後に "}" で終わります。括弧は単にキーをそれ自体でグループ化するのに役立ち、正規表現エンジンが関数へのパラメーターとしてそれを引き出します。

もう 1 つの正規表現の置換 (/^\s+|\s+$/g) は、文字列をトリムするだけです。先頭と末尾の空白をすべて見つけて削除します。ECMAScript 5 には、この機能を組み込みで提供する String.trim() 関数がありますが、確実に使用できるほど普及していません。詳細については、MDN のドキュメントを参照してください。

ただし、このように複数のパスを実行することの賢明さはわかりません。無限ループの可能性を紹介します。

var map = {
    a: "#{b}",
    b: "#{a}"
};

$.tmpl("#{a}", map);

また、マップ内の値に誤って #{...} が含まれ、意図せずに展開される可能性もあります。これらの値がユーザーによって入力された場合、これは特に問題になります。その場合、アプリを無限にループさせたり、他のキーの値を公開したりする可能性を彼に与えただけです。ほとんどのテンプレート エンジンは、この方法でパラメーターを繰り返し置換する機能を提供していません。

于 2013-02-14T17:09:05.803 に答える