Pertanyaan JavaScript setara dengan printf / String.Format


Saya mencari setara JavaScript yang baik dari C / PHP printf() atau untuk programmer C # / Java, String.Format() (IFormatProvider untuk .NET).

Persyaratan dasar saya adalah seribu format pemisah untuk angka untuk saat ini, tetapi sesuatu yang menangani banyak kombinasi (termasuk tanggal) akan bagus.

Saya menyadari Microsoft Ajax perpustakaan menyediakan versi String.Format(), tetapi kami tidak ingin seluruh overhead dari kerangka itu.


1605
2018-01-12 20:02


asal


Jawaban:


Mencoba sprintf () untuk JavaScript.


MemperbaruiOke, jika Anda benar-benar ingin melakukan metode format sederhana sendiri, jangan lakukan penggantian secara berurutan tetapi lakukan secara bersamaan.

Karena sebagian besar proposal lain yang disebutkan gagal ketika mengganti string pengganti sebelumnya juga mengandung urutan format seperti ini:

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

Biasanya Anda mengharapkan keluarannya {1}{0} tetapi keluaran sebenarnya adalah {1}{1}. Jadi, lakukan penggantian sekaligus sebagai pengganti saran fearphage.


684



Membangun solusi yang disarankan sebelumnya:

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

keluaran

ASP sudah mati, tetapi ASP.NET masih hidup! ASP {2}


Jika Anda memilih untuk tidak memodifikasi Stringpurwarupa:

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

Memberi Anda yang lebih akrab:

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

dengan hasil yang sama:

ASP sudah mati, tetapi ASP.NET masih hidup! ASP {2}


1278



Ini lucu karena Stack Overflow sebenarnya memiliki fungsi format sendiri untuk String prototipe yang disebut formatUnicorn. Cobalah! Pergilah ke konsol dan ketik sesuatu seperti:

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

Firebug

Anda mendapatkan hasil ini:

Hello, Gabriel, are you feeling OK?

Anda dapat menggunakan objek, array, dan string sebagai argumen! Saya mendapatkan kodenya dan mengerjakannya kembali untuk menghasilkan versi baru 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;
};

Perhatikan si pintar Array.prototype.slice.call(arguments) panggilan - artinya jika Anda melempar argumen yang berupa string atau angka, bukan objek bergaya JSON tunggal, Anda mendapatkan C # String.Format perilaku hampir persis.

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

Itu karena Array's slice akan memaksa apa pun yang ada di dalamnya arguments menjadi Array, apakah itu asli atau tidak, dan key akan menjadi indeks (0, 1, 2 ...) dari setiap elemen array yang dipaksa menjadi string (misalnya, "0", jadi "\\{0\\}" untuk pola regexp pertama Anda).

Rapi.


366



Format Angka dalam JavaScript

Saya sampai ke halaman pertanyaan ini berharap menemukan caranya nomor format di JavaScript, tanpa memperkenalkan perpustakaan lain. Inilah yang saya temukan:

Membulatkan angka floating-point

Setara dengan sprintf("%.2f", num) dalam JavaScript tampaknya num.toFixed(2), yang format num 2 desimal, dengan pembulatan (tapi lihat komentar @ ars265 tentang Math.round di bawah).

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

Bentuk eksponensial

Setara dengan sprintf("%.2e", num) aku s num.toExponential(2).

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

Basis heksadesimal dan lainnya

Untuk mencetak angka dalam basis B, cobalah num.toString(B). JavaScript mendukung konversi otomatis ke dan dari basis 2 hingga 36 (sebagai tambahan, beberapa browser memilikinya dukungan terbatas untuk enkode base64).

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

Halaman Referensi

Tutorial cepat tentang pemformatan angka JS

Halaman referensi Mozilla untuk toFixed () (dengan tautan ke toPrecision (), toExponential (), toLocaleString (), ...)


288



jsxt, Zippo

Opsi ini lebih cocok.

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

Dengan opsi ini saya dapat mengganti string seperti ini:

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

Dengan kode Anda, yang kedua {0} tidak akan diganti. ;)


168



Dari ES6 yang bisa Anda gunakan string template:

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

Sadarilah bahwa string template dikelilingi oleh backticks `bukan tanda kutip (tunggal).

Untuk informasi lebih lanjut:

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

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

catatan: Periksa situs mozilla untuk menemukan daftar peramban yang didukung.


168



Saya menggunakan fungsi sederhana ini:

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

Itu sangat mirip dengan string.format:

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

90



Ini a minimal implementasi sprintf di JavaScript: hanya "% s" dan "% d", tetapi saya telah membiarkan ruang untuk itu diperpanjang. Tidak ada gunanya bagi OP, tetapi orang lain yang tersandung pada utas ini berasal dari Google mungkin mendapat manfaat darinya.

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

Contoh:

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

Berbeda dengan solusi serupa di balasan sebelumnya, yang satu ini melakukan semua substitusi sekaligus, jadi itu tidak akan menggantikan bagian dari nilai yang sebelumnya diganti.


48



Untuk Node.js pengguna ada util.format yang memiliki fungsi seperti printf:

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

45



Saya terkejut tidak ada yang digunakan reduce, ini adalah fungsi JavaScript asli ringkas dan kuat.

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"

Bagaimana itu bekerja:

mengurangi menerapkan fungsi terhadap akumulator dan setiap elemen dalam larik (dari kiri ke kanan) untuk menguranginya menjadi satu nilai.

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


36