سؤال

أنا أبحث عن سكريبت ما يعادل ج/PHP printf() أو C#/جافا المبرمجين ، String.Format() (IFormatProvider ل .NET).

بلدي الشرط الأساسي هو ألف فاصل شكل أرقام الآن ، ولكن ما أن يعالج الكثير من مجموعات (بما في ذلك التواريخ) سيكون جيدا.

أدركت مايكروسوفت اياكس توفر المكتبة نسخة من String.Format(), ولكن نحن لا نريد كامل النفقات العامة في هذا الإطار.

هل كانت مفيدة؟

المحلول

ومن ES6 على هل يمكن استخدام سلاسل قالب:

let soMany = 10;
console.log(`This is ${soMany} times easier!`);
// "This is 10 times easier!

الإجابة أدناه للحصول على مزيد من التفاصيل.


تحليل وإلا:

sprintf () لجافا سكريبت .


إذا كنت تريد حقا أن تفعل طريقة شكل بسيط لوحدك، لا تفعل بدائل تباعا ولكن القيام بها في وقت واحد.

ولأن معظم المقترحات الأخرى المذكورة تفشل عندما لا تحتوي على استبدال سلسلة استبدال السابق أيضا تسلسل شكل مثل هذا:

"{0}{1}".format("{1}", "{0}")

وعادة تتوقع الإخراج إلى أن {1}{0} لكن الانتاج الفعلي هو {1}{1}. وكذلك الحال بالنسبة لاستبدالها في وقت واحد بدلا من ذلك كما هو الحال في في اقتراح .

نصائح أخرى

وبناء على الحلول المقترحة سابقا:

// First, checks if it isn't implemented yet.
if (!String.prototype.format) {
  String.prototype.format = function() {
    var args = arguments;
    return this.replace(/{(\d+)}/g, function(match, number) { 
      return typeof args[number] != 'undefined'
        ? args[number]
        : match
      ;
    });
  };
}

و"{0} is dead, but {1} is alive! {0} {2}".format("ASP", "ASP.NET")

والمخرجات

<اقتباس فقرة>   

وASP قد مات، ولكن ASP.NET على قيد الحياة! ASP {2}


إذا كنت تفضل عدم تعديل النموذج String ل:

if (!String.format) {
  String.format = function(format) {
    var args = Array.prototype.slice.call(arguments, 1);
    return format.replace(/{(\d+)}/g, function(match, number) { 
      return typeof args[number] != 'undefined'
        ? args[number] 
        : match
      ;
    });
  };
}

ويمنحك أكثر دراية بكثير:

وString.format('{0} is dead, but {1} is alive! {0} {2}', 'ASP', 'ASP.NET');

وبنفس النتيجة:

<اقتباس فقرة>   

وASP قد مات، ولكن ASP.NET على قيد الحياة! ASP {2}

وانه مضحك لتجاوز المكدس في الواقع وظيفة التنسيق الخاصة بها للنموذج String دعا formatUnicorn. جربها! الذهاب إلى وحدة التحكم واكتب شيئا مثل:

"Hello, {name}, are you feeling {adjective}?".formatUnicorn({name:"Gabriel", adjective: "OK"});

ويمكنك الحصول على هذا الإخراج:

وHello, Gabriel, are you feeling OK?

ويمكنك استخدام الكائنات، المصفوفات، وسلاسل كوسائط! حصلت على مدونتها وإعادة صياغة لإنتاج نسخة جديدة من String.prototype.format:

String.prototype.formatUnicorn = String.prototype.formatUnicorn ||
function () {
    "use strict";
    var str = this.toString();
    if (arguments.length) {
        var t = typeof arguments[0];
        var key;
        var args = ("string" === t || "number" === t) ?
            Array.prototype.slice.call(arguments)
            : arguments[0];

        for (key in args) {
            str = str.replace(new RegExp("\\{" + key + "\\}", "gi"), args[key]);
        }
    }

    return str;
};

ملاحظة دعوة ذكية Array.prototype.slice.call(arguments) - وهذا يعني إذا كنت في رمي الحجج التي هي سلاسل أو أرقام، وليس كائن على غرار JSON واحد، وتحصل C # الصورة <لأ href = "https://msdn.microsoft.com/en -US / مكتبة / system.string.format (ت = vs.110) .ASPX # ابتداء "> السلوك String.Format بالضبط تقريبا.

"a{0}bcd{1}ef".formatUnicorn("foo", "bar"); // yields "aFOObcdBARef"

وذلك لأن Array slice سوف يجبر كل ما هو في arguments إلى Array، سواء كان أصلا أم لا، وسوف key يكون مؤشر (0، 1، 2 ...) كل عنصر مجموعة بالإكراه إلى سلسلة (على سبيل المثال "0"، لذلك "\\{0\\}" لأول نمط REGEXP الخاص بك).

وأنيق.

تحليل عدد تنسيق في جافا سكريبت

وصلت إلى هذه الصفحة السؤال على أمل العثور على كيفية الأرقام على تنسيق في جافا سكريبت، دون إدخال بعد مكتبة أخرى. وإليك ما وجدتها:

التقريب أرقام الفاصلة العائمة

ويبدو أن يعادل sprintf("%.2f", num) في جافا سكريبت ليتم num.toFixed(2)، الذي صيغ num إلى 2 عشرية، مع التقريب (ولكن انظر التعليق @ ars265 حول Math.round أدناه).

(12.345).toFixed(2); // returns "12.35" (rounding!)
(12.3).toFixed(2); // returns "12.30" (zero padding)

شكل الأسي

وأي ما يعادل sprintf("%.2e", num) هو num.toExponential(2).

(33333).toExponential(2); // "3.33e+4"

عشري وقواعد أخرى

لطباعة أرقام في قاعدة B، حاول num.toString(B). جافا سكريبت يدعم التحويل التلقائي من وإلى قواعد من 2 إلى 36 (بالإضافة إلى ذلك، بعض المتصفحات لها <لأ href = "https://developer.mozilla.org/en-US/docs/DOM/window.btoa" يختلط = "نوفولو noreferrer "> دعم محدود لbase64 ترميز ).

(3735928559).toString(16); // to base 16: "deadbeef"
parseInt("deadbeef", 16); // from base 16: 3735928559

المرجعي الصفحات

البرنامج التعليمي السريع في عدد JS التنسيق

صفحة مرجع موزيلا لtoFixed () (ومع وصلات إلى toPrecision ()، toExponential ()، toLocaleString ()، ...)

من ES6 على هل يمكن استخدام قالب سلاسل:

let soMany = 10;
console.log(`This is ${soMany} times easier!`);
// "This is 10 times easier!

تكون على علم بأن القالب السلاسل وتحيط بها backticks ` بدلا من (واحد) يقتبس.

لمزيد من المعلومات:

https://developers.google.com/web/updates/2015/01/ES6-Template-Strings

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings

ملاحظة:التحقق من موزيلا الموقع للعثور على قائمة المتصفحات المدعومة.

وjsxt، يقترض

وهذا الخيار يناسب أفضل.

String.prototype.format = function() {
    var formatted = this;
    for (var i = 0; i < arguments.length; i++) {
        var regexp = new RegExp('\\{'+i+'\\}', 'gi');
        formatted = formatted.replace(regexp, arguments[i]);
    }
    return formatted;
};

مع هذا الخيار I يمكن أن تحل محل سلاسل مثل هذه:

'The {0} is dead. Don\'t code {0}. Code {1} that is open source!'.format('ASP', 'PHP');

مع التعليمات البرمجية الثاني {0} لن يتم استبداله. ؛)

وأنا استخدم هذا وظيفة بسيطة:

String.prototype.format = function() {
    var formatted = this;
    for( var arg in arguments ) {
        formatted = formatted.replace("{" + arg + "}", arguments[arg]);
    }
    return formatted;
};

وهذا مشابه جدا لstring.format:

"{0} is dead, but {1} is alive!".format("ASP", "ASP.NET")

ل نود.جي إس المستخدمين هناك <لأ href = "HTTPS: // nodejs.org/api/util.html#util_util_format_format_args "يختلط =" noreferrer "> util.format الذي printf مثل وظائف:

util.format("%s world", "Hello")

وإليك <م> الحد الأدنى تنفيذ sprintf في جافا سكريبت: فقط لا "٪ ليالي" و "٪ د"، ولكن لقد تركت مساحة له أن تمتد. انها غير مجدية لOP، ولكن الناس الآخرين الذين يصادفوا هذا الموضوع يأتي من جوجل قد تستفيد منه.

function sprintf() {
    var args = arguments,
    string = args[0],
    i = 1;
    return string.replace(/%((%)|s|d)/g, function (m) {
        // m is the matched format, e.g. %s, %d
        var val = null;
        if (m[2]) {
            val = m[2];
        } else {
            val = args[i];
            // A switch statement so that the formatter can be extended. Default is %s
            switch (m) {
                case '%d':
                    val = parseFloat(val);
                    if (isNaN(val)) {
                        val = 0;
                    }
                    break;
            }
            i++;
        }
        return val;
    });
}

مثال:

alert(sprintf('Latitude: %s, Longitude: %s, Count: %d', 41.847, -87.661, 'two'));
// Expected output: Latitude: 41.847, Longitude: -87.661, Count: 0

في المقابل مع حلول مماثلة في الردود السابقة، هذا واحد يفعل كل البدائل في دفعة واحدة ، لذلك لن يحل محل أجزاء من القيم استبدال سابقا.

وأنا مندهش لا أحد يستخدم reduce ، وهذا هو موجزة وقوية وظيفة جافا سكريبت الأم.

ES6 (EcmaScript2015)

String.prototype.format = function() {
  return [...arguments].reduce((p,c) => p.replace(/%s/,c), this);
};

console.log('Is that a %s or a %s?... No, it\'s %s!'.format('plane', 'bird', 'SOman'));

function interpolate(theString, argumentArray) {
    var regex = /%s/;
    var _r=function(p,c){return p.replace(regex,c);}
    return argumentArray.reduce(_r, theString);
}

interpolate("%s, %s and %s", ["Me", "myself", "I"]); // "Me, myself and I"

وكيف يعمل:

<اقتباس فقرة>   

تقليل ينطبق على وظيفة ضد تراكم وكل عنصر في مجموعة (من اليسار إلى اليمين) للحد منه لقيمة واحدة.

var _r= function(p,c){return p.replace(/%s/,c)};

console.log(
  ["a", "b", "c"].reduce(_r, "[%s], [%s] and [%s]") + '\n',
  [1, 2, 3].reduce(_r, "%s+%s=%s") + '\n',
  ["cool", 1337, "stuff"].reduce(_r, "%s %s %s")
);

والمبرمجين جافا سكريبت يمكن استخدام String.prototype.sprintf على الشبكي: //github.com/ildar-shaimordanov/jsxt/blob/master/js/String.js . فيما يلي على سبيل المثال:

var d = new Date();
var dateStr = '%02d:%02d:%02d'.sprintf(
    d.getHours(), 
    d.getMinutes(), 
    d.getSeconds());

و+1 يقترض باستثناء أن وظيفة الجسم يجب أن يكون على النحو التالي أو غير ذلك فإنه يلحق السلسلة الحالية على كل التكرار:

String.prototype.format = function() {
    var formatted = this;
    for (var arg in arguments) {
        formatted = formatted.replace("{" + arg + "}", arguments[arg]);
    }
    return formatted;
};

وإضافة إلى الإجابة zippoxer، وأنا استخدام هذه الوظيفة:

String.prototype.format = function () {
    var a = this, b;
    for (b in arguments) {
        a = a.replace(/%[a-z]/, arguments[b]);
    }
    return a; // Make chainable
};

var s = 'Hello %s The magic number is %d.';
s.format('world!', 12); // Hello World! The magic number is 12.

ولدي أيضا نسخة غير النموذج والتي يمكنني استخدامها في كثير من الأحيان لبناء الجملة جافا مثل:

function format() {
    var a, b, c;
    a = arguments[0];
    b = [];
    for(c = 1; c < arguments.length; c++){
        b.push(arguments[c]);
    }
    for (c in b) {
        a = a.replace(/%[a-z]/, b[c]);
    }
    return a;
}
format('%d ducks, 55 %s', 12, 'cats'); // 12 ducks, 55 cats

ES 2015 التحديث

وجميع الأشياء الممتعة الجديدة في ES 2015 يجعل هذا أسهل كثيرا:

function format(fmt, ...args){
    return fmt
        .split("%%")
        .reduce((aggregate, chunk, i) =>
            aggregate + chunk + (args[i] || ""), "");
}

format("Hello %%! I ate %% apples today.", "World", 44);
// "Hello World, I ate 44 apples today."

وأنا أحسب أنه منذ هذا، مثل تلك القديمة، لا تحليل الواقع الحروف، فإنه قد كذلك مجرد استخدام %% رمز واحد. وهذا له فائدة من كونها واضحة وليس مما يجعل من الصعب استخدام % احد. ومع ذلك، إذا كنت بحاجة %% لسبب ما، وكنت بحاجة ليحل محله مع نفسه:

format("I love percentage signs! %%", "%%");
// "I love percentage signs! %%"

سأضيف بلدي الاكتشافات التي وجدت منذ سألت:

للأسف يبدو sprintf لا تحمل ألف فاصل تنسيق مثل .صافي شكل سلسلة.

وأنا استخدم مكتبة صغيرة تسمى String.format لجافا سكريبت حيث يدعم معظم شكل قدرات سلسلة (بما في ذلك الشكل من الأرقام والتواريخ)، ويستخدم بناء الجملة .NET. السيناريو نفسه هو أصغر من 4 كيلو بايت، لذلك لا يخلق الكثير من النفقات العامة.

وأنيقة جدا:

String.prototype.format = function (){
    var args = arguments;
    return this.replace(/\{\{|\}\}|\{(\d+)\}/g, function (curlyBrack, index) {
        return ((curlyBrack == "{{") ? "{" : ((curlyBrack == "}}") ? "}" : args[index]));
    });
};

// Usage:
"{0}{1}".format("{1}", "{0}")

والفضل يعود إلى <ديل> <وأ href = "http://technoblogia.net/2011/11/08/٪D7٪98٪D7٪99٪D7٪A4-٪D7٪A4٪D7٪95٪ D7٪ A0٪ D7٪ A7٪ D7٪ A6٪ D7٪ 99٪ D7٪ 99٪ D7٪ AA-٪ D7٪ A2٪ D7٪ 96٪ D7٪ A8-٪ D7٪ 91٪ D7 javascript-٪ 9C٪ D7 ٪ A2٪ D7٪ 99٪ D7٪ A6٪ D7٪ 95٪ D7٪ 91-٪ D7٪ 9E٪ D7٪ 97٪ D7٪ A8٪ D7٪ 95٪ D7٪ 96٪ D7٪ 95٪ D7٪ AA / "> (وصلة مكسورة) https://gist.github.com/0i0/1519811

وأريد أن تشاركونني حل للمشكلة ". أنا لم إعادة اختراع العجلة ولكن يحاول إيجاد حل على أساس ما يفعل جافا سكريبت بالفعل. ميزة هي أن تحصل على كل تحويلات ضمنية مجانا. وضع نموذج الملكية $ من سلسلة يعطي جملة لطيفة جدا وصغير الحجم (انظر الأمثلة أدناه). ومن ربما ليست الطريقة الأكثر فعالية، ولكن في معظم الحالات التعامل مع الإخراج أنه لا بد من السوبر الأمثل.

String.form = function(str, arr) {
    var i = -1;
    function callback(exp, p0, p1, p2, p3, p4) {
        if (exp=='%%') return '%';
        if (arr[++i]===undefined) return undefined;
        exp  = p2 ? parseInt(p2.substr(1)) : undefined;
        var base = p3 ? parseInt(p3.substr(1)) : undefined;
        var val;
        switch (p4) {
            case 's': val = arr[i]; break;
            case 'c': val = arr[i][0]; break;
            case 'f': val = parseFloat(arr[i]).toFixed(exp); break;
            case 'p': val = parseFloat(arr[i]).toPrecision(exp); break;
            case 'e': val = parseFloat(arr[i]).toExponential(exp); break;
            case 'x': val = parseInt(arr[i]).toString(base?base:16); break;
            case 'd': val = parseFloat(parseInt(arr[i], base?base:10).toPrecision(exp)).toFixed(0); break;
        }
        val = typeof(val)=='object' ? JSON.stringify(val) : val.toString(base);
        var sz = parseInt(p1); /* padding size */
        var ch = p1 && p1[0]=='0' ? '0' : ' '; /* isnull? */
        while (val.length<sz) val = p0 !== undefined ? val+ch : ch+val; /* isminus? */
       return val;
    }
    var regex = /%(-)?(0?[0-9]+)?([.][0-9]+)?([#][0-9]+)?([scfpexd%])/g;
    return str.replace(regex, callback);
}

String.prototype.$ = function() {
    return String.form(this, Array.prototype.slice.call(arguments));
}

وفيما يلي بعض الأمثلة على ذلك:

String.format("%s %s", [ "This is a string", 11 ])
console.log("%s %s".$("This is a string", 11))
var arr = [ "12.3", 13.6 ]; console.log("Array: %s".$(arr));
var obj = { test:"test", id:12 }; console.log("Object: %s".$(obj));
console.log("%c", "Test");
console.log("%5d".$(12)); // '   12'
console.log("%05d".$(12)); // '00012'
console.log("%-5d".$(12)); // '12   '
console.log("%5.2d".$(123)); // '  120'
console.log("%5.2f".$(1.1)); // ' 1.10'
console.log("%10.2e".$(1.1)); // '   1.10e+0'
console.log("%5.3p".$(1.12345)); // ' 1.12'
console.log("%5x".$(45054)); // ' affe'
console.log("%20#2x".$("45054")); // '    1010111111111110'
console.log("%6#2d".$("111")); // '     7'
console.log("%6#16d".$("affe")); // ' 45054'

إذا كنت تبحث للتعامل مع الآلاف فاصل، يجب حقا استخدام toLocaleString () من جافا سكريبت الطبقة لأنه سوف تنسيق سلسلة لمنطقة المستخدم.

تاريخ يمكنك تنسيق التواريخ المحلية والأوقات.

ولدي حل قريب جدا من بيتر، لكنه يتعامل مع عدد وجوه القضية.

if (!String.prototype.format) {
  String.prototype.format = function() {
    var args;
    args = arguments;
    if (args.length === 1 && args[0] !== null && typeof args[0] === 'object') {
      args = args[0];
    }
    return this.replace(/{([^}]*)}/g, function(match, key) {
      return (typeof args[key] !== "undefined" ? args[key] : match);
    });
  };
}

وربما قد يكون أفضل للتعامل مع جميع الحالات اللجج، ولكن لاحتياجاتي هذا هو على ما يرام.

"This is an example from {name}".format({name:"Blaine"});
"This is an example from {0}".format("Blaine");

وPS: هذه هي وظيفة بارد جدا إذا كنت تستخدم ترجمة في أطر القوالب مثل AngularJS :

<h1> {{('hello-message'|translate).format(user)}} <h1>
<h1> {{('hello-by-name'|translate).format( user ? user.name : 'You' )}} <h1>

وأين en.json هو شيء من هذا القبيل

{
    "hello-message": "Hello {name}, welcome.",
    "hello-by-name": "Hello {0}, welcome."
}

PHPJS مشروع وقد كتب تطبيقات جافا سكريبت لكثير من وظائف PHP ل. منذ ظيفة sprintf() PHP هي أساسا نفس printf() C، و تنفيذها جافا سكريبت منه يجب تلبية الاحتياجات الخاصة بك.

وأنا استخدم هذا واحد:

String.prototype.format = function() {
    var newStr = this, i = 0;
    while (/%s/.test(newStr))
        newStr = newStr.replace("%s", arguments[i++])

    return newStr;
}

وبعد ذلك أسميها:

"<h1>%s</h1><p>%s</p>".format("Header", "Just a test!");

واحد نسخة جدا مختلفة قليلا، واحدة انا افضل (هذا واحد الاستخدامات {الثلاثون} الرموز بدلا من {0} الحجج مرقمة، وهذا هو أكثر بكثير توثيق الذات ودعاوى التوطين أفضل بكثير):

String.prototype.format = function(tokens) {
  var formatted = this;
  for (var token in tokens)
    if (tokens.hasOwnProperty(token))
      formatted = formatted.replace(RegExp("{" + token + "}", "g"), tokens[token]);
  return formatted;
};

وهناك تباين ستكون كما يلي:

  var formatted = l(this);

ويدعو وظيفة توطين ل () أولا.

وهناك "sprintf" لجافا سكريبت التي يمكنك العثور على HTTP: //www.webtoolkit INFO. / جافا سكريبت-sprintf.html .

وبالنسبة لأولئك الذين يحبون نود.جي إس و لها <لأ href = "http://nodejs.org/api/util.html#util_util_format_format "> util.format الميزة، لقد انتزعت فقط بها إلى الفانيليا في جافا سكريبت النموذج (مع وظائف الوحيدة التي util.format الاستخدامات):

exports = {};

function isString(arg) {
    return typeof arg === 'string';
}
function isNull(arg) {
    return arg === null;
}
function isObject(arg) {
    return typeof arg === 'object' && arg !== null;
}
function isBoolean(arg) {
    return typeof arg === 'boolean';
}
function isUndefined(arg) {
    return arg === void 0;
}
function stylizeNoColor(str, styleType) {
    return str;
}
function stylizeWithColor(str, styleType) {
    var style = inspect.styles[styleType];

    if (style) {
        return '\u001b[' + inspect.colors[style][0] + 'm' + str +
            '\u001b[' + inspect.colors[style][3] + 'm';
    } else {
        return str;
    }
}
function isFunction(arg) {
    return typeof arg === 'function';
}
function isNumber(arg) {
    return typeof arg === 'number';
}
function isSymbol(arg) {
    return typeof arg === 'symbol';
}
function formatPrimitive(ctx, value) {
    if (isUndefined(value))
        return ctx.stylize('undefined', 'undefined');
    if (isString(value)) {
        var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
                .replace(/'/g, "\\'")
                .replace(/\\"/g, '"') + '\'';
        return ctx.stylize(simple, 'string');
    }
    if (isNumber(value)) {
        // Format -0 as '-0'. Strict equality won't distinguish 0 from -0,
        // so instead we use the fact that 1 / -0 < 0 whereas 1 / 0 > 0 .
        if (value === 0 && 1 / value < 0)
            return ctx.stylize('-0', 'number');
        return ctx.stylize('' + value, 'number');
    }
    if (isBoolean(value))
        return ctx.stylize('' + value, 'boolean');
    // For some reason typeof null is "object", so special case here.
    if (isNull(value))
        return ctx.stylize('null', 'null');
    // es6 symbol primitive
    if (isSymbol(value))
        return ctx.stylize(value.toString(), 'symbol');
}
function arrayToHash(array) {
    var hash = {};

    array.forEach(function (val, idx) {
        hash[val] = true;
    });

    return hash;
}
function objectToString(o) {
    return Object.prototype.toString.call(o);
}
function isDate(d) {
    return isObject(d) && objectToString(d) === '[object Date]';
}
function isError(e) {
    return isObject(e) &&
        (objectToString(e) === '[object Error]' || e instanceof Error);
}
function isRegExp(re) {
    return isObject(re) && objectToString(re) === '[object RegExp]';
}
function formatError(value) {
    return '[' + Error.prototype.toString.call(value) + ']';
}
function formatPrimitiveNoColor(ctx, value) {
    var stylize = ctx.stylize;
    ctx.stylize = stylizeNoColor;
    var str = formatPrimitive(ctx, value);
    ctx.stylize = stylize;
    return str;
}
function isArray(ar) {
    return Array.isArray(ar);
}
function hasOwnProperty(obj, prop) {
    return Object.prototype.hasOwnProperty.call(obj, prop);
}
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
    var name, str, desc;
    desc = Object.getOwnPropertyDescriptor(value, key) || {value: value[key]};
    if (desc.get) {
        if (desc.set) {
            str = ctx.stylize('[Getter/Setter]', 'special');
        } else {
            str = ctx.stylize('[Getter]', 'special');
        }
    } else {
        if (desc.set) {
            str = ctx.stylize('[Setter]', 'special');
        }
    }
    if (!hasOwnProperty(visibleKeys, key)) {
        name = '[' + key + ']';
    }
    if (!str) {
        if (ctx.seen.indexOf(desc.value) < 0) {
            if (isNull(recurseTimes)) {
                str = formatValue(ctx, desc.value, null);
            } else {
                str = formatValue(ctx, desc.value, recurseTimes - 1);
            }
            if (str.indexOf('\n') > -1) {
                if (array) {
                    str = str.split('\n').map(function (line) {
                        return '  ' + line;
                    }).join('\n').substr(2);
                } else {
                    str = '\n' + str.split('\n').map(function (line) {
                        return '   ' + line;
                    }).join('\n');
                }
            }
        } else {
            str = ctx.stylize('[Circular]', 'special');
        }
    }
    if (isUndefined(name)) {
        if (array && key.match(/^\d+$/)) {
            return str;
        }
        name = JSON.stringify('' + key);
        if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
            name = name.substr(1, name.length - 2);
            name = ctx.stylize(name, 'name');
        } else {
            name = name.replace(/'/g, "\\'")
                .replace(/\\"/g, '"')
                .replace(/(^"|"$)/g, "'")
                .replace(/\\\\/g, '\\');
            name = ctx.stylize(name, 'string');
        }
    }

    return name + ': ' + str;
}
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
    var output = [];
    for (var i = 0, l = value.length; i < l; ++i) {
        if (hasOwnProperty(value, String(i))) {
            output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
                String(i), true));
        } else {
            output.push('');
        }
    }
    keys.forEach(function (key) {
        if (!key.match(/^\d+$/)) {
            output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
                key, true));
        }
    });
    return output;
}
function reduceToSingleString(output, base, braces) {
    var length = output.reduce(function (prev, cur) {
        return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
    }, 0);

    if (length > 60) {
        return braces[0] +
            (base === '' ? '' : base + '\n ') +
            ' ' +
            output.join(',\n  ') +
            ' ' +
            braces[1];
    }

    return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
}
function formatValue(ctx, value, recurseTimes) {
    // Provide a hook for user-specified inspect functions.
    // Check that value is an object with an inspect function on it
    if (ctx.customInspect &&
        value &&
        isFunction(value.inspect) &&
            // Filter out the util module, it's inspect function is special
        value.inspect !== exports.inspect &&
            // Also filter out any prototype objects using the circular check.
        !(value.constructor && value.constructor.prototype === value)) {
        var ret = value.inspect(recurseTimes, ctx);
        if (!isString(ret)) {
            ret = formatValue(ctx, ret, recurseTimes);
        }
        return ret;
    }

    // Primitive types cannot have properties
    var primitive = formatPrimitive(ctx, value);
    if (primitive) {
        return primitive;
    }

    // Look up the keys of the object.
    var keys = Object.keys(value);
    var visibleKeys = arrayToHash(keys);

    if (ctx.showHidden) {
        keys = Object.getOwnPropertyNames(value);
    }

    // This could be a boxed primitive (new String(), etc.), check valueOf()
    // NOTE: Avoid calling `valueOf` on `Date` instance because it will return
    // a number which, when object has some additional user-stored `keys`,
    // will be printed out.
    var formatted;
    var raw = value;
    try {
        // the .valueOf() call can fail for a multitude of reasons
        if (!isDate(value))
            raw = value.valueOf();
    } catch (e) {
        // ignore...
    }

    if (isString(raw)) {
        // for boxed Strings, we have to remove the 0-n indexed entries,
        // since they just noisey up the output and are redundant
        keys = keys.filter(function (key) {
            return !(key >= 0 && key < raw.length);
        });
    }

    // Some type of object without properties can be shortcutted.
    if (keys.length === 0) {
        if (isFunction(value)) {
            var name = value.name ? ': ' + value.name : '';
            return ctx.stylize('[Function' + name + ']', 'special');
        }
        if (isRegExp(value)) {
            return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
        }
        if (isDate(value)) {
            return ctx.stylize(Date.prototype.toString.call(value), 'date');
        }
        if (isError(value)) {
            return formatError(value);
        }
        // now check the `raw` value to handle boxed primitives
        if (isString(raw)) {
            formatted = formatPrimitiveNoColor(ctx, raw);
            return ctx.stylize('[String: ' + formatted + ']', 'string');
        }
        if (isNumber(raw)) {
            formatted = formatPrimitiveNoColor(ctx, raw);
            return ctx.stylize('[Number: ' + formatted + ']', 'number');
        }
        if (isBoolean(raw)) {
            formatted = formatPrimitiveNoColor(ctx, raw);
            return ctx.stylize('[Boolean: ' + formatted + ']', 'boolean');
        }
    }

    var base = '', array = false, braces = ['{', '}'];

    // Make Array say that they are Array
    if (isArray(value)) {
        array = true;
        braces = ['[', ']'];
    }

    // Make functions say that they are functions
    if (isFunction(value)) {
        var n = value.name ? ': ' + value.name : '';
        base = ' [Function' + n + ']';
    }

    // Make RegExps say that they are RegExps
    if (isRegExp(value)) {
        base = ' ' + RegExp.prototype.toString.call(value);
    }

    // Make dates with properties first say the date
    if (isDate(value)) {
        base = ' ' + Date.prototype.toUTCString.call(value);
    }

    // Make error with message first say the error
    if (isError(value)) {
        base = ' ' + formatError(value);
    }

    // Make boxed primitive Strings look like such
    if (isString(raw)) {
        formatted = formatPrimitiveNoColor(ctx, raw);
        base = ' ' + '[String: ' + formatted + ']';
    }

    // Make boxed primitive Numbers look like such
    if (isNumber(raw)) {
        formatted = formatPrimitiveNoColor(ctx, raw);
        base = ' ' + '[Number: ' + formatted + ']';
    }

    // Make boxed primitive Booleans look like such
    if (isBoolean(raw)) {
        formatted = formatPrimitiveNoColor(ctx, raw);
        base = ' ' + '[Boolean: ' + formatted + ']';
    }

    if (keys.length === 0 && (!array || value.length === 0)) {
        return braces[0] + base + braces[1];
    }

    if (recurseTimes < 0) {
        if (isRegExp(value)) {
            return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
        } else {
            return ctx.stylize('[Object]', 'special');
        }
    }

    ctx.seen.push(value);

    var output;
    if (array) {
        output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
    } else {
        output = keys.map(function (key) {
            return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
        });
    }

    ctx.seen.pop();

    return reduceToSingleString(output, base, braces);
}
function inspect(obj, opts) {
    // default options
    var ctx = {
        seen: [],
        stylize: stylizeNoColor
    };
    // legacy...
    if (arguments.length >= 3) ctx.depth = arguments[2];
    if (arguments.length >= 4) ctx.colors = arguments[3];
    if (isBoolean(opts)) {
        // legacy...
        ctx.showHidden = opts;
    } else if (opts) {
        // got an "options" object
        exports._extend(ctx, opts);
    }
    // set default options
    if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
    if (isUndefined(ctx.depth)) ctx.depth = 2;
    if (isUndefined(ctx.colors)) ctx.colors = false;
    if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
    if (ctx.colors) ctx.stylize = stylizeWithColor;
    return formatValue(ctx, obj, ctx.depth);
}
exports.inspect = inspect;


// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
inspect.colors = {
    'bold': [1, 22],
    'italic': [3, 23],
    'underline': [4, 24],
    'inverse': [7, 27],
    'white': [37, 39],
    'grey': [90, 39],
    'black': [30, 39],
    'blue': [34, 39],
    'cyan': [36, 39],
    'green': [32, 39],
    'magenta': [35, 39],
    'red': [31, 39],
    'yellow': [33, 39]
};

// Don't use 'blue' not visible on cmd.exe
inspect.styles = {
    'special': 'cyan',
    'number': 'yellow',
    'boolean': 'yellow',
    'undefined': 'grey',
    'null': 'bold',
    'string': 'green',
    'symbol': 'green',
    'date': 'magenta',
    // "name": intentionally not styling
    'regexp': 'red'
};


var formatRegExp = /%[sdj%]/g;
exports.format = function (f) {
    if (!isString(f)) {
        var objects = [];
        for (var j = 0; j < arguments.length; j++) {
            objects.push(inspect(arguments[j]));
        }
        return objects.join(' ');
    }

    var i = 1;
    var args = arguments;
    var len = args.length;
    var str = String(f).replace(formatRegExp, function (x) {
        if (x === '%%') return '%';
        if (i >= len) return x;
        switch (x) {
            case '%s':
                return String(args[i++]);
            case '%d':
                return Number(args[i++]);
            case '%j':
                try {
                    return JSON.stringify(args[i++]);
                } catch (_) {
                    return '[Circular]';
                }
            default:
                return x;
        }
    });
    for (var x = args[i]; i < len; x = args[++i]) {
        if (isNull(x) || !isObject(x)) {
            str += ' ' + x;
        } else {
            str += ' ' + inspect(x);
        }
    }
    return str;
};

وتحصد من: https://github.com/joyent/node/blob/master/ ليب / util.js

لدي أطول قليلا المنسق جافا سكريبت هنا...

يمكنك أن تفعل تنسيق عدة طرق:

  • String.format(input, args0, arg1, ...)
  • String.format(input, obj)
  • "literal".format(arg0, arg1, ...)
  • "literal".format(obj)

أيضا, إذا كان لديك أقول ObjectBase.النموذج الأولي.شكل (مثل مع DateJS) فإنه سيتم استخدام هذا.

أمثلة...

var input = "numbered args ({0}-{1}-{2}-{3})";
console.log(String.format(input, "first", 2, new Date()));
//Outputs "numbered args (first-2-Thu May 31 2012...Time)-{3})"

console.log(input.format("first", 2, new Date()));
//Outputs "numbered args(first-2-Thu May 31 2012...Time)-{3})"

console.log(input.format(
    "object properties ({first}-{second}-{third:yyyy-MM-dd}-{fourth})"
    ,{
        'first':'first'
        ,'second':2
        ,'third':new Date() //assumes Date.prototype.format method
    }
));
//Outputs "object properties (first-2-2012-05-31-{3})"

أنا أيضا مستعارة مع .asFormat وبعض الكشف في المكان في حال كان هناك بالفعل سلسلة.شكل (مثل MS Ajax Toolkit (أكره أن المكتبة).

وفقط في حالة شخص يحتاج إلى وظيفة لمنع تلوث النطاق العالمي، وهنا هي وظيفة أن يفعل نفس الشيء:

  function _format (str, arr) {
    return str.replace(/{(\d+)}/g, function (match, number) {
      return typeof arr[number] != 'undefined' ? arr[number] : match;
    });
  };

لتنسيق الأساسي:

var template = jQuery.validator.format("{0} is not a valid value");
var result = template("abc");

وأنا لم أر String.format البديل:

String.format = function (string) {
    var args = Array.prototype.slice.call(arguments, 1, arguments.length);
    return string.replace(/{(\d+)}/g, function (match, number) {
        return typeof args[number] != "undefined" ? args[number] : match;
    });
};

لاستخدام وظائف نجاح jQuery.ajax (). تمر سوى حجة واحدة وسلسلة استبدال خصائص هذا الكائن ك {PROPERTYNAME}:

String.prototype.format = function () {
    var formatted = this;
    for (var prop in arguments[0]) {
        var regexp = new RegExp('\\{' + prop + '\\}', 'gi');
        formatted = formatted.replace(regexp, arguments[0][prop]);
    }
    return formatted;
};

مثال:

var userInfo = ("Email: {Email} - Phone: {Phone}").format({ Email: "someone@somewhere.com", Phone: "123-123-1234" });

ومع sprintf.js في مكان - يمكن للمرء أن يجعل أنيق القليل الشكل ثينغي

String.prototype.format = function(){
    var _args = arguments 
    Array.prototype.unshift.apply(_args,[this])
    return sprintf.apply(undefined,_args)
}   
// this gives you:
"{%1$s}{%2$s}".format("1", "0")
// {1}{0}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top