JQuery में String.format के बराबर


194

मैं MicrosoftAjax से JQuery के लिए कुछ जावास्क्रिप्ट कोड को स्थानांतरित करने की कोशिश कर रहा हूँ। मैं लोकप्रिय .net तरीकों के MicrosoftAjax में जावास्क्रिप्ट समकक्षों का उपयोग करता हूं, जैसे String.format (), String.startsWith (), आदि क्या jQuery में उनके समकक्ष हैं?


जवाबों:


193

ASP.NET AJAX के लिए स्रोत कोड उपलब्ध है ताकि आप इसे माध्यम से ले सकते हैं और कुछ हिस्सों तो आपको एक अलग जे एस फ़ाइल में उपयोग जारी रखना चाहते शामिल कर सकते हैं, आपके संदर्भ के लिए। या, आप उन्हें jQuery में पोर्ट कर सकते हैं।

यहाँ प्रारूप समारोह है ...

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;
}

और यहाँ एंडवाइट्स हैं और प्रोटोटाइप फ़ंक्शंस के साथ शुरू ...

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);
}

2
ऐसा नहीं लगता कि इसमें बहुत कुछ है। जावास्क्रिप्ट संस्करण में सभी फैंसी नंबर स्वरूपण सामान नहीं है, जाहिर है। blog.stevex.net/index.php/string-formatting-in-csharp
Nosredna

वाह, मैंने वास्तव में इस बारे में पहले से ही सोचा था, लेकिन यह भी सोचा था कि यह लाइसेंस के कारण संभव नहीं था, क्या उन्हें पता नहीं था कि उन्होंने इसे Microsoft Permissive लाइसेंस के तहत जारी किया है, इसके लिए बहुत धन्यवाद
Waleed Eissa

23
लाइसेंस या लाइसेंस नहीं .. कुछ सरल लिखने का केवल एक ही सही तरीका है
adamJLev

1
निर्माण (और फिर त्यागना) प्रत्येक और हर तर्क के लिए एक RegEx वस्तु हर बार प्रारूप कहा जाता है कचरा कलेक्टर से आगे निकल सकता है।
मार्कोस 5

14
चेतावनी: इस रिकर्सिवली स्वरूपित होगा: अगर आपके पास तो {0}{1}, {0}पहले बदल दिया जाएगा, और उसके बाद की सभी घटनाओं {1}में दोनों पहले से ही एवजी पाठ और मूल स्वरूप बदल दिया जाएगा।
Zenexer

147

यह जोश द्वारा पोस्ट किए गए फ़ंक्शन का एक तेज / सरल (और प्रोटोटाइप) भिन्नता है:

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;
};

उपयोग:

'Added {0} by {1} to your collection'.f(title, artist)
'Your balance is {0} USD'.f(77.7) 

मैं इसका इतना उपयोग करता हूं कि मैंने इसे सिर्फ करने के लिए उतारा है f, लेकिन आप अधिक क्रिया का भी उपयोग कर सकते हैं format। जैसे'Hello {0}!'.format(name)


1
आधुनिक ब्राउज़रों के साथ और भी सरल दृष्टिकोण हैं: stackoverflow.com/a/41052964/120296
david

3
@david टेम्पलेट स्ट्रिंग वास्तव में बिल्कुल समान नहीं हैं। वे स्ट्रिंग संघनन के लिए सिंटैक्टिक चीनी हैं, जो अच्छा है लेकिन स्वरूपण के समान नहीं है। वे तुरंत चलते हैं, इसलिए, परिभाषा के बिंदु पर प्रतिस्थापन की गुंजाइश होनी चाहिए। आप उन्हें पाठ फ़ाइल या डेटाबेस में इस वजह से संग्रहीत नहीं कर सकते। वास्तव में, उन्हें कहीं भी स्टोर करने का एकमात्र तरीका उन्हें एक फ़ंक्शन में रखना है। एक स्वरूपित स्ट्रिंग फ़ंक्शन में स्थितीय प्रतिस्थापन होते हैं जो चर के नाम के बारे में परवाह नहीं करते हैं।
krowe2

131

उपरोक्त कार्यों में से कई (जूलियन जेफल्स को छोड़कर) में निम्नलिखित त्रुटि है:

js> '{0} {0} {1} {2}'.format(3.14, 'a{2}bc', 'foo');
3.14 3.14 afoobc foo

या, तर्क सूची के अंत से पीछे की ओर गिनने वाले वेरिएंट के लिए:

js> '{0} {0} {1} {2}'.format(3.14, 'a{0}bc', 'foo');
3.14 3.14 a3.14bc foo

यहाँ एक सही कार्य है। यह जूलियन जेफ्स कोड का एक प्रोटोटाइप संस्करण है, जिसे मैंने थोड़ा सा तंग किया है:

String.prototype.format = function () {
  var args = arguments;
  return this.replace(/\{(\d+)\}/g, function (m, n) { return args[n]; });
};

और यहाँ उसी का थोड़ा और अधिक उन्नत संस्करण है, जो आपको उन्हें दोगुना करके ब्रेसिज़ से बचने की अनुमति देता है:

String.prototype.format = function () {
  var args = arguments;
  return this.replace(/\{\{|\}\}|\{(\d+)\}/g, function (m, n) {
    if (m == "{{") { return "{"; }
    if (m == "}}") { return "}"; }
    return args[n];
  });
};

यह सही ढंग से काम करता है:

js> '{0} {{0}} {{{0}}} {1} {2}'.format(3.14, 'a{2}bc', 'foo');
3.14 {0} {3.14} a{2}bc foo

ब्लेयर मिचेलमोर द्वारा अच्छी अतिरिक्त सुविधाओं के एक समूह के साथ एक और अच्छा कार्यान्वयन यहां दिया गया है: https://web.archive.org/web/20120315214858/http://blairmitchelmore.com/javascript/string.format


और एक और, जिसे मैंने बहुत करीब से नहीं देखा है, लेकिन जो {0: + $ #, 0.00; - $ #, 0.00; 0} जैसे स्वरूपों को लागू करने के लिए लगता है: masterdata.dyndns.org/r/string_format_for_avavascript
gpvos;

ओह, और एक जो पायथन इंटरपोलेशन प्रारूप का उपयोग करता है: code.google.com/p/jquery-utils/wiki/…
gpvos

इस प्रारूप के क्रियान्वयन में मैंने दो टिप्पणियों का उल्लेख किया है जो मास्टरडेट.से
आरआर /

नोट: इस पृष्ठ पर कहीं और ianj का उत्तर आपको संख्यात्मक मापदंडों के बजाय नाम का उपयोग करने में सक्षम बनाता है। यदि आप एक ऐसी विधि को बदलते हैं जो प्रोटोटाइप का उपयोग करती है, तो आपको दूसरे पैरामीटर को slice.call फ़ंक्शन में 1 से 0. तक
बदलना होगा

48

एक प्रारूप फ़ंक्शन बनाया जो एक संग्रह या एक सरणी को तर्क के रूप में लेता है

उपयोग:

format("i can speak {language} since i was {age}",{language:'javascript',age:10});

format("i can speak {0} since i was {1}",'javascript',10});

कोड:

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];
    });
};

5
एक अच्छा, जो सब याद आ रहा है वह है: String.prototyp.format = function (col) {रिटर्न फॉर्मेट (यह, कोल);}
Erik

10
मैं स्ट्रिंग का विस्तार नहीं करना पसंद करता हूं
ianj

3
उपयोग में एक छोटा टाइपो है: 2 वीं पंक्ति होनी चाहिए: प्रारूप ("मैं {0} बोल सकता हूं क्योंकि मैं {1}", 'जावास्क्रिप्ट', 10) था;
गिलियूम गेंड्रे

विस्तारित स्ट्रिंग का उपयोग करना क्यों पसंद नहीं करते String.prototype?
किकेनेट

36

एक (कुछ हद तक) आधिकारिक विकल्प है: jQuery.validator.format

JQuery सत्यापन प्लगिन 1.6 (कम से कम) के साथ आता है। .NET में पाए
जाने वाले समान String.Format

फिक्स्ड टूटी हुई लिंक संपादित करें



13

यद्यपि वास्तव में क्यू क्या नहीं पूछ रहा था, मैंने एक ऐसा बनाया है जो समान है लेकिन क्रमांकित के बजाय नामित प्लेसहोल्डर्स का उपयोग करता है। मैं व्यक्तिगत रूप से तर्कों का नाम देना पसंद करता हूं और इसे एक तर्क के रूप में एक वस्तु में भेजता हूं (अधिक क्रिया, लेकिन बनाए रखना आसान है)।

String.prototype.format = function (args) {
    var newStr = this;
    for (var key in args) {
        newStr = newStr.replace('{' + key + '}', args[key]);
    }
    return newStr;
}

यहाँ एक उदाहरण उपयोग है ...

alert("Hello {name}".format({ name: 'World' }));

8

एक आधुनिक ब्राउज़र का उपयोग करना, जो EcmaScript 2015 (ES6) का समर्थन करता है, आप टेम्पलेट स्ट्रिंग्स का आनंद ले सकते हैं । स्वरूपण के बजाय, आप सीधे चर मान को इसमें इंजेक्ट कर सकते हैं:

var name = "Waleed";
var message = `Hello ${name}!`;

ध्यान दें टेम्प्लेट स्ट्रिंग को बैक-टिक्स (`) का उपयोग करके लिखा जाना है।


6

अब तक प्रस्तुत किए गए उत्तरों में से किसी में भी एक बार आरंभ करने और बाद के उपयोग के लिए नियमित भावों को संग्रहीत करने के लिए संलग्नक का उपयोग करने का कोई स्पष्ट अनुकूलन नहीं है।

// 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}"));

इसके अलावा, यदि कोई पहले से मौजूद है तो कोई भी उदाहरण प्रारूप () कार्यान्वयन का सम्मान नहीं करता है।


2
rx2 अनावश्यक है, मेरा कार्यान्वयन देखें; rx1 में आपके (कोष्ठक) हैं, लेकिन वे उस मूल्य का उपयोग नहीं करते हैं जो वे आंतरिक फ़ंक्शन को पास करते हैं। इसके अलावा, मुझे लगता है कि यह जावास्क्रिप्ट इंजन में करने के लिए एक स्पष्ट अनुकूलन है । क्या आप सुनिश्चित हैं कि आधुनिक ब्राउज़र पहले से ही पर्दे के पीछे इस अनुकूलन को नहीं करते हैं? पर्ल ने 1990 में ऐसा किया था। आप सही हैं कि यह जाँचने के लिए फ़ंक्शन के चारों ओर एक आवरण होना चाहिए कि क्या यह पहले से ही लागू है।
gpvos

1
इसके अलावा, परीक्षण (आर्ग्स [idx] === "") मुझे बहुत ही अच्छा लग रहा है: यह पहले से ही उस लाइन पर पहले परीक्षण द्वारा कवर किया गया है, क्योंकि अपरिभाषित! == ""।
gpvos

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];             
        });
    }

बुलेट प्रूफ नहीं लेकिन काम करता है अगर आप समझदारी से इसका उपयोग करें।


4

पिछले सत्र के अंत में, लेकिन मैं अभी दिए गए उत्तरों को देख रहा हूं और मेरी योग्यता है:

उपयोग:

var one = strFormat('"{0}" is not {1}', 'aalert', 'defined');
var two = strFormat('{0} {0} {1} {2}', 3.14, 'a{2}bc', 'foo');

तरीका:

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

परिणाम:

"aalert" is not defined
3.14 3.14 a{2}bc foo

3

अब आप खाका साहित्य का उपयोग कर सकते हैं :

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
मैं टेम्पलेट शाब्दिकों के बारे में उत्साहित था जब तक कि मैंने देखा कि वे केवल तब काम करते हैं जब स्ट्रिंग को प्रतिस्थापन चर के साथ परिभाषित किया जाता है। मेरे लिए जो उन्हें बहुत बेकार बनाता है; किसी एक कारण से या मेरे अधिकांश तार को उस कोड से अलग से परिभाषित किया गया है जो उन्हें पॉप्युलेट / उपयोग करता है।
पत्थर

2

यहां मेरा संस्करण है जो '{' से बचने में सक्षम है, और उन अनसाइनड प्लेस होल्डर्स को साफ करता है।

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

निम्नलिखित उत्तर शायद सबसे अधिक कुशल है, लेकिन तर्क के केवल 1 से 1 mappings के लिए उपयुक्त होने का चेतावनी है। यह समवर्ती स्ट्रिंग्स के सबसे तेज़ तरीके का उपयोग करता है (स्ट्रिंगर के समान: स्ट्रिंग्स की सरणी, जुड़ गया)। यह मेरा अपना कोड है। शायद एक बेहतर विभाजक की जरूरत है।

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 आर्ग की मैपिंग है। रीजेक्स के प्रदर्शन के साथ-साथ अधिक कुशल क्यूज प्रतिस्थापित () और नया रेगेक्स () एकल विभाजन की तुलना में अधिक सीपीयू चक्रों का उपयोग करता है।
स्किचन

-1 की जरूरत नहीं। नहीं, यह व्यापक रूप से लागू नहीं है, लेकिन वह सही है, यह थोड़ा अधिक कुशल होगा। अब, लेखक के लिए, एक आर्किटेक्चर सवाल: क्लाइंट पर इतने बड़े डेटासेट के साथ किस तरह का अनुप्रयोग होगा जो इस तरह के अनुकूलन की आवश्यकता होगी?
माइकल ब्लैकबर्न

अच्छा बिंदु माइकल ब्लैकबर्न। ज्यादातर स्थितियां शायद ठीक हैं। मेरे मामले में मैं डेटा का एक अच्छा हिस्सा (उत्पाद समूह के भीतर उत्पाद विविधताएं, इसलिए संभवतः सैकड़ों वेरिएंट) के साथ काम कर रहा था और मेरी राय यह है कि चूंकि उपयोगकर्ताओं के पास आमतौर पर कई ब्राउज़र टैब खुले होते हैं और हर वेबसाइट पर बहुत सी सीपीयू चूसने की प्रवृत्ति होती है मैंने उच्च दक्षता बनाए रखने के लिए इस कार्यान्वयन को प्राथमिकता दी।
स्किचन

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>

यह यूआरआई के लिए ठीक है, लेकिन सामान्य उपयोग के लिए, एक स्ट्रिंग होने पर दोनों प्रारूप होते हैं और घटक बहुत भंगुर होते हैं। क्या होगा यदि आपके स्ट्रिंग में अल्पविराम हो?
माइकल ब्लैकबर्न

0

मुझे जोश स्टोडोला के काम करने का जवाब नहीं मिला, लेकिन निम्नलिखित ने मेरे लिए काम किया। के विनिर्देश पर ध्यान दें prototype। (आईई, एफएफ, क्रोम और सफारी पर परीक्षण किया गया।):

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.replace () के रिटर्न मान के साथ पुन: असाइन किया जाता है, तो यह अछूता रहता है।
gpvos

0

ऊपर adamJLev के शानदार उत्तर पर विस्तार से , यहाँ टाइपस्क्रिप्ट संस्करण है:

// 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;
};

0

मेरे पास एक प्लंकर है जो इसे स्ट्रिंग प्रोटोटाइप में जोड़ता है: string.format यह केवल कुछ अन्य उदाहरणों की तरह छोटा नहीं है, बल्कि बहुत अधिक लचीला है।

उपयोग c # संस्करण के समान है:

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

इसके अलावा, नाम और वस्तु गुणों का उपयोग करने के लिए जोड़ा समर्थन

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

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}))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.