Bagaimana cara menggunakan java.String.format di Scala?

322

Saya mencoba menggunakan .formatmetode string. Tetapi jika saya menempatkan% 1,% 2, dll dalam string, java.util.UnknownFormatConversionException dilemparkan ke bagian kode Java yang membingungkan:

private void checkText(String s) {

    int idx;

    // If there are any '%' in the given string, we got a bad format
    // specifier.
    if ((idx = s.indexOf('%')) != -1) {
        char c = (idx > s.length() - 2 ? '%' : s.charAt(idx + 1));
        throw new UnknownFormatConversionException(String.valueOf(c));
    }
}

Dari sini saya mengerti bahwa %arang dilarang. Jika demikian, lalu apa yang harus saya gunakan untuk placeholder argumen?

Saya menggunakan Scala 2.8.

Ivan
sumber

Jawaban:

302

Meskipun semua respons sebelumnya benar, semuanya ada di Jawa. Berikut ini adalah contoh Scala:

val placeholder = "Hello %s, isn't %s cool?"
val formatted = placeholder.format("Ivan", "Scala")

Saya juga punya posting blog tentang membuat formatseperti %operator Python yang mungkin berguna.

pr1001
sumber
2
Banyak contoh dalam dokumentasi JDK: docs.oracle.com/javase/7/docs/api/java/util/…
angelcervera
1
Anda dapat menyederhanakan dengan menerapkan formatlangsung ke string literal:"Hello %s, isn't %s cool?".format("Ivan", "Scala")
sotrh
298

Anda tidak perlu menggunakan angka untuk menunjukkan posisi. Secara default, posisi argumen hanyalah urutan yang muncul dalam string.

Berikut ini contoh cara yang tepat untuk menggunakan ini:

String result = String.format("The format method is %s!", "great");
// result now equals  "The format method is great!".

Anda akan selalu menggunakan %diikuti oleh beberapa karakter lain untuk membiarkan metode tahu bagaimana seharusnya menampilkan string. %smungkin yang paling umum, dan itu hanya berarti bahwa argumen harus diperlakukan sebagai string.

Saya tidak akan mencantumkan setiap opsi, tetapi saya akan memberikan beberapa contoh hanya untuk memberi Anda ide:

// we can specify the # of decimals we want to show for a floating point:
String result = String.format("10 / 3 = %.2f", 10.0 / 3.0);
// result now equals  "10 / 3 = 3.33"

// we can add commas to long numbers:
result = String.format("Today we processed %,d transactions.", 1000000);
// result now equals  "Today we processed 1,000,000 transactions."

String.formathanya menggunakan java.util.Formatter, jadi untuk deskripsi lengkap tentang opsi Anda dapat melihat javadocs Formatter .

Dan, seperti yang disebutkan BalusC, Anda akan melihat dalam dokumentasi yang dimungkinkan untuk mengubah urutan argumen default jika perlu. Namun, mungkin satu-satunya saat Anda perlu / ingin melakukan ini adalah jika Anda menggunakan argumen yang sama lebih dari sekali.

TM.
sumber
127

Alih-alih melihat kode sumber, Anda harus membaca sintaks String.format () dan javadoc .

Anda menentukan format nilai setelah%. Misalnya untuk bilangan bulat desimal itu d, dan untuk String itu adalah s:

String aString = "world";
int aInt = 20;
String.format("Hello, %s on line %d",  aString, aInt );

Keluaran:

Hello, world on line 20

Untuk melakukan apa yang Anda mencoba (menggunakan indeks argumen), Anda menggunakan: *n*$,

String.format("Line:%2$d. Value:%1$s. Result: Hello %1$s at line %2$d", aString, aInt );

Keluaran:

Line:20. Value:world. Result: Hello world at line 20
OscarRyz
sumber
70

Anda bisa menggunakan ini;

String.format("%1$s %2$s %2$s %3$s", "a", "b", "c");

Keluaran:

abbc

Engin Ardıç
sumber
1
Saya belum pernah melihat penggunaan seperti ini, sangat berguna ketika mengulangi string, bagus!
Domi.Zhang
8
+1 ini lebih seperti apa yang Anda gunakan sebagai pengembang C #. Di sana, kami menggunakan {0}dan {1}bukannya %1$dan %2$.
ashes999
@ ashes999 Saya dari c # land juga. Aku sudah terbiasa dengan tanda kurung bernomor sampai aku lupa itu bukan cara standar dalam melakukan sesuatu. Melihat tanda persen membawa semuanya kembali!
JonnyRaa
13

Perhatikan juga bahwa Scala memperluas String dengan sejumlah metode (melalui konversi implisit ke WrappedString yang dibawa oleh Predef) sehingga Anda juga dapat melakukan hal berikut:

val formattedString = "Hello %s, isn't %s cool?".format("Ivan", "Scala")
denis phillips
sumber
11

Referensi resmi adalah kelas Formatter.

Alberto Segura
sumber
10

Dalam Scala 2.10

val name = "Ivan"
val weather = "sunny"

s"Hello $name, it's $weather today!"
Londo
sumber
1
Saya menganggap bahwa ini hanyalah sintaksis khusus dari rangkaian string (artinya $ name dan $ weather adalah referensi sulit untuk variabel yang didefinisikan sebelumnya). Namun String.Format mengambil template sebagai parameter dan dengan demikian memungkinkan misalnya untuk mengambil kembali template dari file properti dan semacamnya. - Apakah itu mungkin dengan sintaks di atas?
chiccodoro
Ini disebut interpolasi String, dalam scala ada dua jenis: s "" dan f "", 's' adalah string sederhana dan 'f' mirip dengan printf, Anda bahkan dapat mendefinisikan interpolasi Anda sendiri (saya belum mencoba). The $nameberarti bahwa itu harus mengganti dengan nilai variabel name, Anda juga bisa melakukan operasi di interpolasi, misalnyas"Hello ${name.toUpperCase}, it's $weather today!"
Londo
3

Ini adalah daftar apa yang String.formatbisa dilakukan. Hal yang sama berlaku untukprintf

int i = 123;
o.printf( "|%d|%d|%n" ,       i, -i );      // |123|-123|
o.printf( "|%5d|%5d|%n" ,     i, -i );      // |  123| –123|
o.printf( "|%-5d|%-5d|%n" ,   i, -i );      // |123  |-123 |
o.printf( "|%+-5d|%+-5d|%n" , i, -i );      // |+123 |-123 |
o.printf( "|%05d|%05d|%n%n",  i, -i );      // |00123|-0123|

o.printf( "|%X|%x|%n", 0xabc, 0xabc );      // |ABC|abc|
o.printf( "|%04x|%#x|%n%n", 0xabc, 0xabc ); // |0abc|0xabc|

double d = 12345.678;
o.printf( "|%f|%f|%n" ,         d, -d );    // |12345,678000|     |-12345,678000|
o.printf( "|%+f|%+f|%n" ,       d, -d );    // |+12345,678000| |-12345,678000|
o.printf( "|% f|% f|%n" ,       d, -d );    // | 12345,678000| |-12345,678000|
o.printf( "|%.2f|%.2f|%n" ,     d, -d );    // |12345,68| |-12345,68|
o.printf( "|%,.2f|%,.2f|%n" ,   d, -d );    // |12.345,68| |-12.345,68|
o.printf( "|%.2f|%(.2f|%n",     d, -d );    // |12345,68| |(12345,68)|
o.printf( "|%10.2f|%10.2f|%n" , d, -d );    // |  12345,68| | –12345,68|
o.printf( "|%010.2f|%010.2f|%n",d, -d );    // |0012345,68| |-012345,68|

String s = "Monsterbacke";
o.printf( "%n|%s|%n", s );                  // |Monsterbacke|
o.printf( "|%S|%n", s );                    // |MONSTERBACKE|
o.printf( "|%20s|%n", s );                  // |        Monsterbacke|
o.printf( "|%-20s|%n", s );                 // |Monsterbacke        |
o.printf( "|%7s|%n", s );                   // |Monsterbacke|
o.printf( "|%.7s|%n", s );                  // |Monster|
o.printf( "|%20.7s|%n", s );                // |             Monster|

Date t = new Date();
o.printf( "%tT%n", t );                     // 11:01:39
o.printf( "%tD%n", t );                     // 04/18/08
o.printf( "%1$te. %1$tb%n", t );            // 18. Apr
PRO_gramista
sumber
1

Walaupun @Londo menyebut interpolator string Scala, saya pikir interpolator string "f" Scala lebih relevan dengan pertanyaan awal. Contoh yang digunakan beberapa waktu dalam tanggapan lain juga dapat ditulis (karena Scala 2.10) dengan cara ini:

scala> val name = "Ivan"
name: String = Ivan
scala> val thing = "Scala"
thing: String = Scala
scala> val formatted = f"Hello $name%s, isn't $thing%s cool?"
formatted: String = Hello Ivan, isn't Scala cool?

Koneksi ke pertanyaan awal adalah untuk menyadari bahwa:

  • formatteddidefinisikan dengan string yang diawali dengan huruf "f". Ini adalah interpolator string "f" (pemformatan).
  • Interpolator string "f" digunakan java.util.Formatter
  • java.lang.String.format menggunakan hal yang sama java.util.Formatter

Hal yang menyenangkan tentang interpolasi string adalah memungkinkan Anda melihat variabel mana yang diganti secara langsung ke dalam string daripada harus mencocokkannya dengan argumen ke String.formatmetode.

Reid Spencer
sumber
0

Dalam scala, untuk Interpolasi string kita memiliki $ yang menyelamatkan hari dan membuat hidup kita lebih mudah:

Sebagai Contoh: Anda ingin mendefinisikan fungsi yang mengambil nama dan umur input dan mengatakan Halo dengan nama dan mengatakan usianya. Itu bisa ditulis seperti ini:

def funcStringInterpolationDemo(name:String,age:Int)=s"Hey ! my name is $name and my age is $age"

Karenanya, Saat Anda memanggil fungsi ini: seperti ini:

funcStringInterpolationDemo("Shivansh",22)

Hasilnya adalah:

Hey ! my name is Shivansh and my age is 22

Anda dapat menulis kode untuk mengubahnya di baris yang sama, seperti jika Anda ingin menambahkan 10 tahun ke usia!

maka fungsinya bisa:

def funcStringInterpolationDemo(name:String,age:Int)=s"Hey ! my name is $name and my age is ${age+10}"

Dan sekarang hasilnya adalah:

Hey ! my name is Shivansh and my age is 32
Shiv4nsh
sumber