문제

C/PHP와 동등한 좋은 JavaScript를 찾고 있습니다. printf() 또는 C#/Java 프로그래머의 경우, String.Format() (IFormatProvider .NET의 경우).

내 기본 요구 사항은 현재 숫자에 대한 천 개에 대한 분리기 형식이지만 많은 조합 (날짜 포함)을 처리하는 것이 좋을 것입니다.

나는 Microsoft의 것을 알고 있습니다 Ajax 라이브러리는 버전을 제공합니다 String.Format(), 그러나 우리는 해당 프레임 워크의 전체 오버 헤드를 원하지 않습니다.

도움이 되었습니까?

해결책

ES6에서 템플릿 문자열을 사용할 수 있습니다.

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

Kim 's를 참조하십시오 대답 자세한 내용은 아래에 있습니다.


그렇지 않으면:

노력하다 JavaScript 용 Sprintf ().


스스로 간단한 형식 메소드를 실제로하고 싶다면 교체품을 연속적으로 수행하지 말고 동시에 수행하십시오.

이전 교체의 교체 문자열이 다음과 같은 형식 시퀀스를 포함 할 때 언급 된 대부분의 제안이 실패하기 때문에.

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

일반적으로 출력이 될 것으로 예상됩니다 {1}{0} 그러나 실제 출력은입니다 {1}{1}. 대신 동시에 교체 할 수 있습니다 FearPhage의 제안.

다른 팁

이전에 제안 된 솔루션을 바탕으로 :

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

Firebug

이 출력을 얻습니다.

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#을 얻을 수 있습니다. String.Format 거의 정확한 행동.

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

그것은 ~ 때문에 Array'에스 slice 무엇이든 강요 할 것입니다 argumentsArray, 원래 여부에 관계없이 key 각 배열 요소의 인덱스 (0, 1, 2 ...)는 문자열 (예 : "0")으로 강요됩니다. "\\{0\\}" 첫 번째 regexp 패턴).

정돈된.

JavaScript의 숫자 형식

나는이 질문 페이지에 도착했다. 형식 번호 JavaScript에서는 또 다른 도서관을 소개하지 않고. 내가 찾은 내용은 다음과 같습니다.

반올림 플로팅 지점 번호

동등한 sprintf("%.2f", num) JavaScript에서는 것 같습니다 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"

16 진수 및 기타 기지

기본 B에서 숫자를 인쇄하려면 시도하십시오 num.toString(B). JavaScript는 기지 2에서 36으로의 자동 변환을 지원합니다 (또한 일부 브라우저는 Base64 인코딩에 대한 제한된 지원).

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

참조 페이지

JS 번호 형식에 대한 빠른 튜토리얼

tofixed () 용 Mozilla 참조 페이지 (toprecision (), toexponential (), tolocalestring (), ...)에 대한 링크가 포함되어 있습니다.

ES6에서 사용할 수 있습니다 템플릿 문자열:

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

템플릿 문자열이 있음을 알아야합니다 백 티크로 둘러싸여 있습니다 `(단일) 인용문 대신.

자세한 정보 :

https://developers.google.com/web/updates/2015/01/es6-template-strings

https://developer.mozilla.org/en-us/docs/web/javaScript/reference/template_strings

참고 : Mozilla 사이트를 확인하여 지원되는 브라우저 목록을 찾으십시오.

JSXT, Zippo

이 옵션은 더 잘 맞습니다.

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

이 옵션으로 다음과 같은 문자열을 교체 할 수 있습니다.

'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")

을 위한 node.js 사용자가 있습니다 util.format Printf와 같은 기능이 있습니다.

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

여기에 있습니다 최소 JavaScript에서 Sprintf의 구현 : "%s"및 "%d"만 수행하지만 확장 할 공간이 남았습니다. OP에는 쓸모가 없지만 Google에서 오는이 스레드를 우연히 발견하는 다른 사람들이 그로부터 혜택을받을 수 있습니다.

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, 이것은 기본 간결하고 강력한 JavaScript 기능입니다.

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

<ES6

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

JavaScript 프로그래머는 String.prototype.sprintf at을 사용할 수 있습니다 https://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 ZIPPO 기능 본체가 아래에 있거나 그렇지 않으면 모든 반복의 현재 문자열에 추가되어야한다는 점을 제외하고.

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.

또한 Java와 같은 구문에 더 자주 사용하는 비 프로토 타입 버전이 있습니다.

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 업데이트

2015 년 ES의 멋진 새로운 것들이 훨씬 쉬워집니다.

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는 .NET의 문자열 형식과 같은 천명 분리기 형식을 처리하지 않는 것 같습니다.

나는 작은 라이브러리를 사용합니다 JavaScript 용 string.format 대부분의 형식 문자열 기능 (숫자 및 날짜 형식 포함)을 지원하고 .NET 구문을 사용합니다. 스크립트 자체는 4KB보다 작으므로 많은 오버 헤드를 생성하지 않습니다.

매우 우아한 :

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

크레딧이 간다 (깨진 링크) https://gist.github.com/0i0/1519811

'문제'에 대한 솔루션을 공유하고 싶습니다. 나는 바퀴를 다시 발명하지 않았지만 JavaScript가 이미하는 일을 바탕으로 솔루션을 찾으려고 노력합니다. 장점은 모든 암시 적 전환을 무료로 얻는다는 것입니다. String의 프로토 타입 속성 $를 설정하면 매우 멋지고 컴팩트 한 구문이 나타납니다 (아래 예제 참조). 아마도 가장 효율적인 방법은 아니지만 대부분의 경우 출력을 다루는 것은 매우 최적화 될 필요는 없습니다.

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'

수천 명의 분리기를 처리하려면 JavaScript에서 Tolocalestring ()을 실제로 사용해야합니다. 숫자 클래스는 사용자 영역의 문자열을 형식화하므로 클래스.

JavaScript 날짜 클래스는 현지화 날짜와 시간을 형식화 할 수 있습니다.

나는 Peter 's와 매우 가까운 솔루션을 가지고 있지만 숫자와 객체 케이스를 다룹니다.

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

어쩌면 All Deeps 사례를 다루는 것이 더 나을 수도 있지만, 내 필요에 따라 이것은 괜찮습니다.

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

추신 :이 기능은 템플릿 프레임 워크에서 번역을 사용하는 경우 매우 멋지다. 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 기능에 대한 JavaScript 구현을 작성했습니다. PHP 이후 sprintf() 함수는 기본적으로 C와 동일합니다 printf(), 그들의 JavaScript 구현 당신의 필요를 충족시켜야합니다.

나는 이것을 사용한다 :

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!");

매우 약간 다른 버전 중 하나 인 내가 선호하는 버전 (이것은 {xxx} 토큰을 사용하여 {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);

먼저 l () 현지화 함수를 호출합니다.

JavaScript 용 "Sprintf"가 있습니다. http://www.webtoolkit.info/javaScript-sprintf.html.

좋아하는 사람들을 위해 node.js 그리고 그것 util.format 기능, 방금 바닐라 JavaScript 양식으로 추출했습니다 (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/lib/util.js

JavaScript를 위해 약간 더 긴 Formatter가 있습니다 여기...

여러 가지 방법으로 서식 할 수 있습니다.

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

또한 ObjectBase.prototype.format (예 : 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와 별명을 가지고 있었고 이미 string.format (예 : Ajax 툴킷과 같은 Library를 싫어합니다).

누군가가 글로벌 범위 오염을 방지하기 위해 기능이 필요한 경우를 대비하여 다음과 같은 기능이 있습니다.

  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 () 성공 함수와 함께 사용합니다. 단일 인수 만 전달하고 문자열을 전달합니다.

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