String.Format in JavaScript
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:
// 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:
// 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