在JavaScript中使用String.Format?

时间:2010-03-28 22:17:57

标签: c# .net javascript

这让我疯了。我相信我问了同样的问题,但我再也找不到了(我使用Stack Overflow搜索,Google搜索,手动搜索我的帖子,搜索我的代码)。

我想要的东西就像C#String.Format,你可以在那里做类似

的事情
string format = String.Format("Hi {0}",name);

当然只是为JavaScript而且有一个人给了我一个简单的答案,它不像jQuery插件或任何东西,但我认为你做了一些JSON的东西,它起作用并且使用起来很简单。

我为我的生活找不到这篇文章。

我在我的代码中确实有这个,但我似乎找不到任何使用它的东西,而且我很确定我曾经使用它几次:

String.prototype.format = function(o)
{
    return this.replace(/{([^{}]*)}/g,
       function(a, b)
       {
           var r = o[b];
           return typeof r === 'string' ? r : a;
       }
    );
};

19 个答案:

答案 0 :(得分:70)

调整MsAjax string的代码。

只需删除所有_validateParams代码,您就可以在JavaScript中使用完整的.NET字符串类。

好的,我解放了msajax字符串类,删除了所有msajax依赖项。它非常好用,就像.NET字符串类一样,包括trim函数,endsWith / startsWith等等。

P.S。 - 我保留了所有Visual Studio JavaScript IntelliSense助手和XmlDocs。如果您不使用Visual Studio,它们是无害的,但如果您愿意,可以删除它们。

<script src="script/string.js" type="text/javascript"></script>
<script type="text/javascript">
    var a = String.format("Hello {0}!", "world");
    alert(a);

</script>

String.js

// String.js - liberated from MicrosoftAjax.js on 03/28/10 by Sky Sanders
// permalink: http://stackoverflow.com/a/2534834/2343

/*
    Copyright (c) 2009, CodePlex Foundation
    All rights reserved.

    Redistribution and use in source and binary forms, with or without modification, are permitted
    provided that the following conditions are met:

    *   Redistributions of source code must retain the above copyright notice, this list of conditions
        and the following disclaimer.

    *   Redistributions in binary form must reproduce the above copyright notice, this list of conditions
        and the following disclaimer in the documentation and/or other materials provided with the distribution.

    *   Neither the name of CodePlex Foundation nor the names of its contributors may be used to endorse or
        promote products derived from this software without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED
    WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
    IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</textarea>
*/

(function(window) {

    $type = String;
    $type.__typeName = 'String';
    $type.__class = true;

    $prototype = $type.prototype;
    $prototype.endsWith = function String$endsWith(suffix) {
        /// <summary>Determines whether the end of this instance matches the specified string.</summary>
        /// <param name="suffix" type="String">A string to compare to.</param>
        /// <returns type="Boolean">true if suffix matches the end of this instance; otherwise, false.</returns>
        return (this.substr(this.length - suffix.length) === suffix);
    }

    $prototype.startsWith = function String$startsWith(prefix) {
        /// <summary >Determines whether the beginning of this instance matches the specified string.</summary>
        /// <param name="prefix" type="String">The String to compare.</param>
        /// <returns type="Boolean">true if prefix matches the beginning of this string; otherwise, false.</returns>
        return (this.substr(0, prefix.length) === prefix);
    }

    $prototype.trim = function String$trim() {
        /// <summary >Removes all leading and trailing white-space characters from the current String object.</summary>
        /// <returns type="String">The string that remains after all white-space characters are removed from the start and end of the current String object.</returns>
        return this.replace(/^\s+|\s+$/g, '');
    }

    $prototype.trimEnd = function String$trimEnd() {
        /// <summary >Removes all trailing white spaces from the current String object.</summary>
        /// <returns type="String">The string that remains after all white-space characters are removed from the end of the current String object.</returns>
        return this.replace(/\s+$/, '');
    }

    $prototype.trimStart = function String$trimStart() {
        /// <summary >Removes all leading white spaces from the current String object.</summary>
        /// <returns type="String">The string that remains after all white-space characters are removed from the start of the current String object.</returns>
        return this.replace(/^\s+/, '');
    }

    $type.format = function String$format(format, args) {
        /// <summary>Replaces the format items in a specified String with the text equivalents of the values of   corresponding object instances. The invariant culture will be used to format dates and numbers.</summary>
        /// <param name="format" type="String">A format string.</param>
        /// <param name="args" parameterArray="true" mayBeNull="true">The objects to format.</param>
        /// <returns type="String">A copy of format in which the format items have been replaced by the   string equivalent of the corresponding instances of object arguments.</returns>
        return String._toFormattedString(false, arguments);
    }

    $type._toFormattedString = function String$_toFormattedString(useLocale, args) {
        var result = '';
        var format = args[0];

        for (var i = 0; ; ) {
            // Find the next opening or closing brace
            var open = format.indexOf('{', i);
            var close = format.indexOf('}', i);
            if ((open < 0) && (close < 0)) {
                // Not found: copy the end of the string and break
                result += format.slice(i);
                break;
            }
            if ((close > 0) && ((close < open) || (open < 0))) {

                if (format.charAt(close + 1) !== '}') {
                    throw new Error('format stringFormatBraceMismatch');
                }

                result += format.slice(i, close + 1);
                i = close + 2;
                continue;
            }

            // Copy the string before the brace
            result += format.slice(i, open);
            i = open + 1;

            // Check for double braces (which display as one and are not arguments)
            if (format.charAt(i) === '{') {
                result += '{';
                i++;
                continue;
            }

            if (close < 0) throw new Error('format stringFormatBraceMismatch');


            // Find the closing brace

            // Get the string between the braces, and split it around the ':' (if any)
            var brace = format.substring(i, close);
            var colonIndex = brace.indexOf(':');
            var argNumber = parseInt((colonIndex < 0) ? brace : brace.substring(0, colonIndex), 10) + 1;

            if (isNaN(argNumber)) throw new Error('format stringFormatInvalid');

            var argFormat = (colonIndex < 0) ? '' : brace.substring(colonIndex + 1);

            var arg = args[argNumber];
            if (typeof (arg) === "undefined" || arg === null) {
                arg = '';
            }

            // If it has a toFormattedString method, call it.  Otherwise, call toString()
            if (arg.toFormattedString) {
                result += arg.toFormattedString(argFormat);
            }
            else if (useLocale && arg.localeFormat) {
                result += arg.localeFormat(argFormat);
            }
            else if (arg.format) {
                result += arg.format(argFormat);
            }
            else
                result += arg.toString();

            i = close + 1;
        }

        return result;
    }

})(window);

答案 1 :(得分:42)

这是我使用的。我在实用程序文件中定义了此函数:

  String.format = function() {
      var s = arguments[0];
      for (var i = 0; i < arguments.length - 1; i++) {       
          var reg = new RegExp("\\{" + i + "\\}", "gm");             
          s = s.replace(reg, arguments[i + 1]);
      }
      return s;
  }

我称之为:

var greeting = String.format("Hi, {0}", name);

我不记得我在哪里找到了它,但它对我来说非常有用。我喜欢它,因为语法与C#版本相同。

答案 2 :(得分:20)

你可以做一系列替换:

function format(str)
{
    for(i = 1; i < arguments.length; i++)
    {
        str = str.replace('{' + (i - 1) + '}', arguments[i]);
    }
    return str;
}

更好的方法是使用替换函数参数:

function format(str, obj) {
    return str.replace(/\{\s*([^}\s]+)\s*\}/g, function(m, p1, offset, string) {
        return obj[p1]
    })
}

这样您就可以提供索引和命名参数:

var arr = ['0000', '1111', '2222']

arr.a = 'aaaa'

str = format(" { 0 } , {1}, { 2}, {a}", arr)
// returns 0000 , 1111, 2222, aaaa

答案 3 :(得分:12)

这是一个有用的字符串格式化函数,使用正则表达式和捕获:

function format (fmtstr) {
  var args = Array.prototype.slice.call(arguments, 1);
  return fmtstr.replace(/\{(\d+)\}/g, function (match, index) {
    return args[index];
  });
}

字符串的格式可以像C#String.Format:

var str = format('{0}, {1}!', 'Hello', 'world');
console.log(str); // prints "Hello, world!"

格式化将正确的变量放在正确的位置,即使它们出现乱序:

var str = format('{1}, {0}!', 'Hello', 'world');
console.log(str); // prints "world, Hello!"

希望这有帮助!

答案 4 :(得分:11)

没有第三方功能:

string format = "Hi {0}".replace('{0}', name)

有多个参数:

string format = "Hi {0} {1}".replace('{0}', name).replace('{1}', lastname)

答案 5 :(得分:3)

.NET Framework中的

String.Format方法有multiple signatures。我喜欢的the most在其原型中使用params关键字,即:

public static string Format(
    string format,
    params Object[] args
)

使用此版本,您不仅可以向其传递可变数量的参数,还可以传递数组参数。

因为我喜欢Jeremy提供的直接解决方案,所以我想稍微延伸一下:

var StringHelpers = {
    format: function(format, args) {
        var i;
        if (args instanceof Array) {
            for (i = 0; i < args.length; i++) {
                format = format.replace(new RegExp('\\{' + i + '\\}', 'gm'), args[i]);
            }
            return format;
        }
        for (i = 0; i < arguments.length - 1; i++) {
            format = format.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i + 1]);
        }
        return format;
    }
};

现在,您可以按以下方式使用JavaScript版String.Format

StringHelpers.format("{0}{1}", "a", "b")

StringHelpers.format("{0}{1}", ["a", "b"])

答案 6 :(得分:2)

只需制作并使用此功能:

function format(str, args) {
   for (i = 0; i < args.length; i++)
      str = str.replace("{" + i + "}", args[i]);
   return str;
}

如果您不想更改 str 参数,那么在for循环之前,将其克隆(复制)到新字符串(制作<的新副本< strong> str ),并在for循环中设置副本,最后返回它而不是参数本身。

在C#(夏普)中,只需拨打String.Clone()即可轻松创建副本,但我不知道如何使用JavaScript,但您可以在Google上搜索或在互联网上浏览并了解相关方法这样做。

我刚刚在JavaScript中提供了关于字符串格式的想法。

答案 7 :(得分:2)

在ECMAScript 6中使用模板文字:

var customer = { name: "Foo" }
var card = { amount: 7, product: "Bar", unitprice: 42 }
var message = `Hello ${customer.name},
               want to buy ${card.amount} ${card.product} for
               a total of ${card.amount * card.unitprice} bucks?`

答案 8 :(得分:2)

这是一个适用于String.prototype的解决方案:

String.prototype.format = function() {
    var s = this;
    for (var i = 0; i < arguments.length; i++) {       
        var reg = new RegExp("\\{" + i + "\\}", "gm");             
        s = s.replace(reg, arguments[i]);
    }
    return s;
}

答案 9 :(得分:2)

根据@ roydukkey的回答,对运行时进行了一些优化(它缓存了正则表达式):

(function () {
    if (!String.prototype.format) {
        var regexes = {};
        String.prototype.format = function (parameters) {
            for (var formatMessage = this, args = arguments, i = args.length; --i >= 0;)
                formatMessage = formatMessage.replace(regexes[i] || (regexes[i] = RegExp("\\{" + (i) + "\\}", "gm")), args[i]);
            return formatMessage;
        };
        if (!String.format) {
            String.format = function (formatMessage, params) {
                for (var args = arguments, i = args.length; --i;)
                    formatMessage = formatMessage.replace(regexes[i - 1] || (regexes[i - 1] = RegExp("\\{" + (i - 1) + "\\}", "gm")), args[i]);
                return formatMessage;
            };
        }
    }
})();

答案 10 :(得分:1)

这是一个允许原型和功能选项的解决方案。

// --------------------------------------------------------------------
// Add prototype for 'String.format' which is c# equivalent
//
// String.format("{0} i{2}a night{1}", "This", "mare", "s ");
// "{0} i{2}a night{1}".format("This", "mare", "s ");
// --------------------------------------------------------------------

if(!String.format)
    String.format = function(){
        for (var i = 0, args = arguments; i < args.length - 1; i++)
            args[0] = args[0].replace("{" + i + "}", args[i + 1]);
        return args[0];
    };
if(!String.prototype.format && String.format)
    String.prototype.format = function(){
        var args = Array.prototype.slice.call(arguments).reverse();
        args.push(this);
        return String.format.apply(this, args.reverse())
    };

享受。

答案 11 :(得分:1)

您的函数已将JSON对象作为参数:

string format = "Hi {foo}".replace({
    "foo": "bar",
    "fizz": "buzz"
});

如果你注意到,代码:

var r = o[b];

查看您的参数(o)并使用其中的键值对来解析“替换”

答案 12 :(得分:1)

我刚开始将Java的String.format()移植到JavaScript。您可能会发现它也很有用。

它支持这样的基本内容:

StringFormat.format("Hi %s, I like %s", ["Rob", "icecream"]);

结果是

Hi Rob, I like icecream.

但更高级的数字格式和日期格式如:

StringFormat.format("Duke's Birthday: %1$tA %1$te %1$tB, %1$tY", [new Date("2014-12-16")]);

Duke's Birthday: Tuesday 16 December, 2014

请参阅示例中的更多内容。

见这里:https://github.com/RobAu/javascript.string.format

答案 13 :(得分:1)

if (!String.prototype.format) {
    String.prototype.format = function () {
        var args = arguments;
        return this.replace(/{(\d+)}/g, function (match, number) {
            return typeof args[number] != 'undefined'
              ? args[number]
              : match
            ;
        });
    };
}

用法:

'{0}-{1}'.format('a','b');
// Result: 'a-b'

JSFiddle

答案 14 :(得分:1)

以下是我的two cents

req.body = {
    currency : "USD",
    item_name_1: "something",
    item_price_1: "something else",
    item_name_2: "something",
    item_price_2: "something else",
    item_name_3: "something",
    item_price_3: "something else",
    address: "some address"   
    itemCount: 3     
}

答案 15 :(得分:1)

除了您正在修改String原型这一事实外,您提供的功能没有任何问题。您可以这样使用它的方式:

"Hello {0},".format(["Bob"]);

如果您想将它作为一个独立的功能,您可以稍微改变它:

function format(string, object) {
    return string.replace(/{([^{}]*)}/g,
       function(match, group_match)
       {
           var data = object[group_match];
           return typeof data === 'string' ? data : match;
       }
    );
}

Vittore的方法也很好;调用他的函数时,每个额外的格式化选项都作为参数传递,而你的期望是一个对象。

这实际上是John Resig的micro-templating engine

答案 16 :(得分:1)

//Add "format" method to the string class
//supports:  "Welcome {0}. You are the first person named {0}".format("David");
//       and "First Name:{} Last name:{}".format("David","Wazy");
//       and "Value:{} size:{0} shape:{1} weight:{}".format(value, size, shape, weight)
String.prototype.format = function () {
    var content = this;
    for (var i = 0; i < arguments.length; i++) {
        var target = '{' + i + '}';
        content=content.split(target).join(String(arguments[i]))
        content = content.replace("{}", String(arguments[i]));
    }
    return content;
}
alert("I {} this is what {2} want and {} works for {2}!".format("hope","it","you"))

您可以使用位置和&#34;命名&#34;进行混合和匹配。使用此功能替换位置。

答案 17 :(得分:0)

使用sprintf

您可以在{{}}找到此库的功能。

答案 18 :(得分:0)

String.prototype.format = function () {
    var formatted = this;
    for (var arg in arguments) {
        formatted = formatted.split('{' + arg + '}').join(arguments[arg]);
    }
    return formatted;
};

用法:

'Hello {0}!'.format('Word')

->

Hello World!

'He{0}{0}o World!'.format('l')

-> Hello World! '{0} {1}!'.format('Hello', 'Word')

-> Hello World! '{0}!'.format('Hello {1}', 'Word')