Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

String.Format in JavaScript

5.00/5 (3 votes)
31 May 2011CPOL 19.9K  
You can simplify the replacement by not translating the strings to numbers as all array subscripts are treated as strings, and by representing '{' and '}' as more user-friendly substitutions (e.g. {{} and {}}) rather than {-1} and {-2} which can be pre-populated into the replacements array....
You can simplify the replacement by not translating the strings to numbers as all array subscripts are treated as strings, and by representing '{' and '}' as more user-friendly substitutions (e.g. {{} and {}}) rather than {-1} and {-2} which can be pre-populated into the replacements array. Also, the substitutable values can be passed as an arguments list rather than as a single array argument (again, simpler for the user). The net effect of these is that your function can be reduced to:
JavaScript
// This is the function.
String.prototype.format = function() {
    var args = arguments;
    args['{'] = '{';
    args['}'] = '}';
    return this.replace(
        /{({|}|-?[0-9]+)}/g,
        function(item) {
            var result = args[item.substring(1, item.length - 1)];
            return typeof result == 'undefined' ? '' : result;
            }
        );
};

// Sample usage.
var str = "She {1} {0}{2} by the {0}{3}. {{}^_^{}}";
str = str.format("sea", "sells", "shells", "shore");
alert(str);


Note that not all versions of JavaScript support string.replace(regexp, function). You can add support for it using:
JavaScript
//  Add support for string.replace(regexp, function) and for string.replace(string, function) if not already available
if  ('a'.replace(/a/, function() { return ''; }))    // True if function argument does not work
{
    String.prototype._replaceNative = String.prototype.replace; // Old version

    String.prototype.replace    =   // New version
        function(test, replacement)
        {
            if  (typeof replacement == 'function')
                if  (typeof test == 'string')
                {
                    // Change all occurrences
                    // Beware: Function need not give same result every time
                    var strs    = this.split(test);
                    for (var i = 1; i < strs.length; i++)
                        strs[i - 1] += replacement(test);
                        return  strs.join('');
                }   // if
                else if (test.global)   // Global RegExp
                {
                    var result  = '';
                    test.lastIndex  = 0;    // Reset
                    do
                    {
                        var oldIndex    = test.lastIndex;
                        test.exec(this);    // Get next match
                        if  (test.lastIndex)
                            result  += this.substring(oldIndex, RegExp.leftContext.length)
                                + replacement(RegExp.lastMatch);
                    }   // do
                    while   (test.lastIndex);

                    return  result + this.substring(oldIndex);
                }   // else if
                else    // Assume non-global RegExp
                {
                    test.lastIndex  = 0;    // Reset
                    var results = test.exec(this);  // Get first match
                    return  (   results
                        ?   this.substring(0, results.index)
                                + replacement(results[0])
                                + this.substring(results.index + results[0].length)
                        :   this    // No match found
                        );
                }   // else
            else    // Use native method
            {
                // Pass all arguments in case of new features that we are unaware of
                arguments.constructor   = Array;
                return  String.prototype._replaceNative.apply(this, arguments);
            }   // else
        }   // String.prototype.replace

}   // if

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)