jQuery中类似于String.format的函数是什么?

205

我正在尝试将一些JavaScript代码从MicrosoftAjax迁移到JQuery。 我使用MicrosoftAjax中流行的.net方法的JavaScript等效方法,例如String.format(),String.startsWith()等。 在jQuery中是否有与它们相当的方法?


2
请参考以下链接,了解JavaScript中类似于printf的字符串格式化函数:https://dev59.com/YXRB5IYBdhLWcg3weXOX - John
22个回答

4
这是我的:
String.format = function(tokenised){
        var args = arguments;
        return tokenised.replace(/{[0-9]}/g, function(matched){
            matched = matched.replace(/[{}]/g, "");
            return args[parseInt(matched)+1];             
        });
    }

虽然不是百分之百可靠,但只要合理使用,它就能发挥作用。


3

这是我能够转义 '{' 并清理那些未分配占位符的版本。

function getStringFormatPlaceHolderRegEx(placeHolderIndex) {
    return new RegExp('({)?\\{' + placeHolderIndex + '\\}(?!})', 'gm')
}

function cleanStringFormatResult(txt) {
    if (txt == null) return "";

    return txt.replace(getStringFormatPlaceHolderRegEx("\\d+"), "");
}

String.prototype.format = function () {
    var txt = this.toString();
    for (var i = 0; i < arguments.length; i++) {
        var exp = getStringFormatPlaceHolderRegEx(i);
        txt = txt.replace(exp, (arguments[i] == null ? "" : arguments[i]));
    }
    return cleanStringFormatResult(txt);
}
String.format = function () {
    var s = arguments[0];
    if (s == null) return "";

    for (var i = 0; i < arguments.length - 1; i++) {
        var reg = getStringFormatPlaceHolderRegEx(i);
        s = s.replace(reg, (arguments[i + 1] == null ? "" : arguments[i + 1]));
    }
    return cleanStringFormatResult(s);
}

2

以下答案可能是最有效的,但有一个警告:只适用于参数的一对一映射。这使用最快的字符串连接方式(类似于字符串构建器:字符串数组,拼接)。这是我自己的代码。不过可能需要更好的分隔符。

String.format = function(str, args)
{
    var t = str.split('~');
    var sb = [t[0]];
    for(var i = 0; i < args.length; i++){
        sb.push(args[i]);
        sb.push(t[i+1]);
    }
    return sb.join("");
}

使用方法如下:

alert(String.format("<a href='~'>~</a>", ["one", "two"]));

2
被接受的答案是最好的答案。我提供了一个独特的答案,适用于想要挤出尽可能多效率(长循环)并且具有1:1参数映射的场景。更高效,因为replace()和new Regex()以及执行正则表达式肯定比单个split()使用更多的CPU周期。 - Skystrider
不需要-1。不,它并不是普遍适用的,但他是正确的,这会稍微更有效率一些。 现在,针对作者的一个架构问题:什么样的应用程序会在客户端处理如此大的数据集,以至于需要这种优化呢? - Michael Blackburn
Michael Blackburn说得很好。大多数情况可能都没问题。但在我的情况下,我处理了大量数据(产品组内的产品变体,可能有数百个变体),我认为由于用户通常会打开许多浏览器选项卡,并且每个网站 tend to suck a lot of CPU,因此我更喜欢这种实现方式以保持高效率。 - Skystrider

2
现在你可以使用 模板字面量

var w = "the Word";
var num1 = 2;
var num2 = 3;

var long_multiline_string = `This is very long
multiline templete string. Putting somthing here:
${w}
I can even use expresion interpolation:
Two add three = ${num1 + num2}
or use Tagged template literals
You need to enclose string with the back-tick (\` \`)`;

console.log(long_multiline_string);


3
在我看到模板字符串只有在字符串与要替换的变量一起定义时才能使用之后,我对它们感到兴奋不已。对我来说,这使得它们几乎没有什么用处;由于种种原因,我的大多数字符串都是与填充/使用它们的代码分开定义的。 - stone

2

这违反了DRY��则,但这是一个简洁的解决方案:

var button = '<a href="{link}" class="btn">{text}</a>';
button = button.replace('{text}','Authorize on GitHub').replace('{link}', authorizeUrl);

0
<html>
<body>
<script type="text/javascript">
   var str="http://xyz.html?ID={0}&TId={1}&STId={2}&RId={3},14,480,3,38";
   document.write(FormatString(str));
   function FormatString(str) {
      var args = str.split(',');
      for (var i = 0; i < args.length; i++) {
         var reg = new RegExp("\\{" + i + "\\}", "");             
         args[0]=args[0].replace(reg, args [i+1]);
      }
      return args[0];
   }
</script>
</body>
</html>

这对于 URI 来说很好,但是对于一般用途,让一个字符串包含格式和组件是非常脆弱的。如果您的字符串包含逗号怎么办? - Michael Blackburn

0

我无法让Josh Stodola的答案起作用,但以下方法适用于我。请注意prototype的规范。(在IE、FF、Chrome和Safari上测试通过。):

String.prototype.format = function() {
    var s = this;
    if(t.length - 1 != args.length){
        alert("String.format(): Incorrect number of arguments");
    }
    for (var i = 0; i < arguments.length; i++) {       
        var reg = new RegExp("\\{" + i + "\\}", "gm");
        s = s.replace(reg, arguments[i]);
    }
    return s;
}

s 应该是 克隆this,以避免成为破坏性方法,但这并不是必要的。


这不是一种破坏性的方法。当 s 被重新赋值为 s.replace() 的返回值时,原始值仍然保持不变。 - gpvos

0

你也可以使用替换来闭合数组,就像这样。

var url = '/getElement/_/_/_'.replace(/_/g, (_ => this.ar[this.i++]).bind({ar: ["invoice", "id", 1337],i: 0}))
> '/getElement/invoice/id/1337

或者你可以尝试使用bind

'/getElement/_/_/_'.replace(/_/g, (function(_) {return this.ar[this.i++];}).bind({ar: ["invoice", "id", 1337],i: 0}))

0
// Regex cache
_stringFormatRegex = null;
//
/// Formats values from {0} to {9}. Usage: stringFormat( 'Hello {0}', 'World' );
stringFormat = function () {
    if (!_stringFormatRegex) {
        // Initialize
        _stringFormatRegex = [];
        for (var i = 0; i < 10; i++) {
            _stringFormatRegex[i] = new RegExp("\\{" + i + "\\}", "gm");
        }
    }
    if (arguments) {
        var s = arguments[0];
        if (s) {
            var L = arguments.length;
            if (1 < L) {
                var r = _stringFormatRegex;
                for (var i = 0; i < L - 1; i++) {
                    var reg = r[i];
                    s = s.replace(reg, arguments[i + 1]);
                }
            }
        }
        return s;
    }
}

0

在adamJLev的出色答案上面的基础上,这里是TypeScript版本:

// Extending String prototype
interface String {
    format(...params: any[]): string;
}

// Variable number of params, mimicking C# params keyword
// params type is set to any so consumer can pass number
// or string, might be a better way to constraint types to
// string and number only using generic?
String.prototype.format = function (...params: any[]) {
    var s = this,
        i = params.length;

    while (i--) {
        s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), params[i]);
    }

    return s;
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接