I'm trying to move some JavaScript code from MicrosoftAjax to JQuery. I use the JavaScript equivalents in MicrosoftAjax of the popular .net methods, e.g. String.format(), String.startsWith(), etc. Are there equivalents to them in jQuery?
The source code for ASP.NET AJAX is available for your reference, so you can pick through it and include the parts you want to continue using into a separate JS file. Or, you can port them to jQuery.
Here is the format function...
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;
}
And here are the endsWith and startsWith prototype functions...
String.prototype.endsWith = function (suffix) {
return (this.substr(this.length - suffix.length) === suffix);
}
String.prototype.startsWith = function(prefix) {
return (this.substr(0, prefix.length) === prefix);
}
substring
if you have those kinds of concerns, but I certainly wouldn't be too worried about that; usually when you are formatting a string you have three of these, at best. –
Graubert {0}{1}
, {0}
will be replaced first, and then all occurrences of {1}
in both the already-substituted text and the original format will be replaced. –
Inhambane format recursively
? –
Swampy This is a faster/simpler (and prototypical) variation of the function that Josh posted:
String.prototype.format = String.prototype.f = function() {
var s = this,
i = arguments.length;
while (i--) {
s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]);
}
return s;
};
Usage:
'Added {0} by {1} to your collection'.f(title, artist)
'Your balance is {0} USD'.f(77.7)
I use this so much that I aliased it to just f
, but you can also use the more verbose format
. e.g. 'Hello {0}!'.format(name)
Many of the above functions (except Julian Jelfs's) contain the following error:
js> '{0} {0} {1} {2}'.format(3.14, 'a{2}bc', 'foo');
3.14 3.14 afoobc foo
Or, for the variants that count backwards from the end of the argument list:
js> '{0} {0} {1} {2}'.format(3.14, 'a{0}bc', 'foo');
3.14 3.14 a3.14bc foo
Here's a correct function. It's a prototypal variant of Julian Jelfs's code, which I made a bit tighter:
String.prototype.format = function () {
var args = arguments;
return this.replace(/\{(\d+)\}/g, function (m, n) { return args[n]; });
};
And here is a slightly more advanced version of the same, which allows you to escape braces by doubling them:
String.prototype.format = function () {
var args = arguments;
return this.replace(/\{\{|\}\}|\{(\d+)\}/g, function (m, n) {
if (m == "{{") { return "{"; }
if (m == "}}") { return "}"; }
return args[n];
});
};
This works correctly:
js> '{0} {{0}} {{{0}}} {1} {2}'.format(3.14, 'a{2}bc', 'foo');
3.14 {0} {3.14} a{2}bc foo
Here is another good implementation by Blair Mitchelmore, with a bunch of nice extra features: https://web.archive.org/web/20120315214858/http://blairmitchelmore.com/javascript/string.format
Made a format function that takes either a collection or an array as arguments
Usage:
format("i can speak {language} since i was {age}",{language:'javascript',age:10});
format("i can speak {0} since i was {1}",'javascript',10});
Code:
var format = function (str, col) {
col = typeof col === 'object' ? col : Array.prototype.slice.call(arguments, 1);
return str.replace(/\{\{|\}\}|\{(\w+)\}/g, function (m, n) {
if (m == "{{") { return "{"; }
if (m == "}}") { return "}"; }
return col[n];
});
};
String.prototype
? –
Swampy There is an (somewhat) official option: jQuery.validator.format.
Comes with jQuery Validation Plugin 1.6 (at least).
Quite similar to the String.Format
found in .NET.
Edit Fixed broken link.
If you're using the validation plugin you can use:
jQuery.validator.format("{0} {1}", "cool", "formatting") = 'cool formatting'
http://docs.jquery.com/Plugins/Validation/jQuery.validator.format#templateargumentargumentN...
Though not exactly what the Q was asking for, I've built one that is similar but uses named placeholders instead of numbered. I personally prefer having named arguments and just send in an object as an argument to it (more verbose, but easier to maintain).
String.prototype.format = function (args) {
var newStr = this;
for (var key in args) {
newStr = newStr.replace('{' + key + '}', args[key]);
}
return newStr;
}
Here's an example usage...
alert("Hello {name}".format({ name: 'World' }));
Using a modern browser, which supports EcmaScript 2015 (ES6), you can enjoy Template Strings. Instead of formatting, you can directly inject the variable value into it:
var name = "Waleed";
var message = `Hello ${name}!`;
Note the template string has to be written using back-ticks (`).
None of the answers presented so far has no obvious optimization of using enclosure to initialize once and store regular expressions, for subsequent usages.
// DBJ.ORG string.format function
// usage: "{0} means 'zero'".format("nula")
// returns: "nula means 'zero'"
// place holders must be in a range 0-99.
// if no argument given for the placeholder,
// no replacement will be done, so
// "oops {99}".format("!")
// returns the input
// same placeholders will be all replaced
// with the same argument :
// "oops {0}{0}".format("!","?")
// returns "oops !!"
//
if ("function" != typeof "".format)
// add format() if one does not exist already
String.prototype.format = (function() {
var rx1 = /\{(\d|\d\d)\}/g, rx2 = /\d+/ ;
return function() {
var args = arguments;
return this.replace(rx1, function($0) {
var idx = 1 * $0.match(rx2)[0];
return args[idx] !== undefined ? args[idx] : (args[idx] === "" ? "" : $0);
});
}
}());
alert("{0},{0},{{0}}!".format("{X}"));
Also, none of the examples respects format() implementation if one already exists.
Way past the late season but I've just been looking at the answers given and have my tuppence worth:
Usage:
var one = strFormat('"{0}" is not {1}', 'aalert', 'defined');
var two = strFormat('{0} {0} {1} {2}', 3.14, 'a{2}bc', 'foo');
Method:
function strFormat() {
var args = Array.prototype.slice.call(arguments, 1);
return arguments[0].replace(/\{(\d+)\}/g, function (match, index) {
return args[index];
});
}
Result:
"aalert" is not defined
3.14 3.14 a{2}bc foo
Here's mine:
String.format = function(tokenised){
var args = arguments;
return tokenised.replace(/{[0-9]}/g, function(matched){
matched = matched.replace(/[{}]/g, "");
return args[parseInt(matched)+1];
});
}
Not bullet proof but works if you use it sensibly.
Here's my version that is able to escape '{', and clean up those unassigned place holders.
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);
}
The following answer is probably the most efficient but has the caveat of only being suitable for 1 to 1 mappings of arguments. This uses the fastest way of concatenating strings (similar to a stringbuilder: array of strings, joined). This is my own code. Probably needs a better separator though.
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("");
}
Use it like:
alert(String.format("<a href='~'>~</a>", ["one", "two"]));
This violates DRY principle, but it's a concise solution:
var button = '<a href="{link}" class="btn">{text}</a>';
button = button.replace('{text}','Authorize on GitHub').replace('{link}', authorizeUrl);
Now you can use Template Literals:
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);
I couldn't get Josh Stodola's answer to work, but the following worked for me. Note the specification of prototype
. (Tested on IE, FF, Chrome, and 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
really should be a clone of this
so as not to be a destructive method, but it's not really necessary.
<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>
Expanding on adamJLev's great answer above, here is the TypeScript version:
// 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;
};
I have a plunker that adds it to the string prototype: string.format It is not just as short as some of the other examples, but a lot more flexible.
Usage is similar to c# version:
var str2 = "Meet you on {0}, ask for {1}";
var result2 = str2.format("Friday", "Suzy");
//result: Meet you on Friday, ask for Suzy
//NB: also accepts an array
Also, added support for using names & object properties
var str1 = "Meet you on {day}, ask for {Person}";
var result1 = str1.format({day: "Thursday", person: "Frank"});
//result: Meet you on Thursday, ask for Frank
var result1 = str1.format({day: "Thursday"});
Meet you on Thursday, ask for {Person} –
Biak You can also closure array with replacements like this.
var url = '/getElement/_/_/_'.replace(/_/g, (_ => this.ar[this.i++]).bind({ar: ["invoice", "id", 1337],i: 0}))
> '/getElement/invoice/id/1337
or you can try bind
'/getElement/_/_/_'.replace(/_/g, (function(_) {return this.ar[this.i++];}).bind({ar: ["invoice", "id", 1337],i: 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;
}
}
Using functional programming:
// 'Hello, {0} {1}'.format('FirstName', 'LastName') -> 'Hello, FirstName LastName'
String.prototype.format = function () {
const initialValue = this.toString();
const numberOfArguments = arguments.length || 0;
const formattedValue = [...Array(numberOfArguments)].reduce((accumulator, currentValue, index) => {
const replacementPattern = new RegExp('\\{' + index + '\\}', 'gm');
const updatedValued = accumulator.replace(replacementPattern, arguments[index]);
return updatedValued;
}, initialValue);
return formattedValue;
};
© 2022 - 2024 — McMap. All rights reserved.