2010-09-12 4 views
309

Próbuję użyć metody ciąg znaków w postaci .format. Ale jeśli umieścić% 1,% 2, itd w ciągu, java.util.UnknownFormatConversionException jest wyrzucane wskazując mylące kawałek kodu źródłowego Javy:Jak korzystać z java.String.format w Scala?

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

Z tego rozumiem, że % char jest zabronione. Jeśli tak, to co powinienem użyć dla argumentów zastępczych?

Używam Scala 2.8.

Odpowiedz

293

Podczas gdy wszystkie poprzednie odpowiedzi są poprawne, wszystkie znajdują się w Javie. Oto przykład Scala:

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

Mam też blogu o making format like Python's % operator, które mogą być użyteczne.

+56

Nazywanie „ciąg” Zmienna spala jakieś dodatkowe cylces cpu mózg zrealizować jego nie typ, ale tylko nazwa zmiennej. Chcę tylko podkreślić, że takie małe rzeczy mogą coś zmienić, gdy coś wyjaśniasz. –

+1

Dobra uwaga, naprawię to. – pr1001

+29

+1 za dopasowaną wiadomość do Ivana! –

297

Nie trzeba używać liczb do wskazania pozycji. Domyślnie pozycja argumentu jest po prostu kolejnością, w jakiej pojawia się w ciągu znaków.

Oto przykład właściwy sposób wykorzystać to:

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

Będziesz zawsze używać % następnie niektórych innych znaków pozwolić metoda wiedzieć jak powinien wyświetlić napis. %s jest prawdopodobnie najczęstszym, a to po prostu oznacza, że ​​argument powinien być traktowany jako ciąg.

nie będzie lista wszystkich opcji, ale dam kilka przykładów wystarczy, aby dać Ci pomysł:

// 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.format tylko używa java.util.Formatter, więc dla pełnego opisu opcji możesz zobacz Formatter javadocs.

I, jak wspomina BalusC, zobaczysz w dokumentacji, że możesz zmienić domyślną kolejność argumentów, jeśli potrzebujesz. Jednak prawdopodobnie jedyny raz, kiedy będziesz potrzebować/chcesz to zrobić, to jeśli używasz tego samego argumentu więcej niż jeden raz.

126

Zamiast patrzeć na kod źródłowy, należy zapoznać się z javadoc String.format() i Formatter syntax.

Użytkownik określa format wartości po%. Na przykład dla liczb całkowitych dziesiętnych jest d, a ciąg jest s:

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

wyjściowa:

Hello, world on line 20 

Aby zrobić to, czego próbowałem (użyć indeksu argument), możesz użyć: *n*$,

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

wyjściowa:

Line:20. Value:world. Result: Hello world at line 20 
13

Należy również pamiętać, że Scala rozciąga String z kilkoma metodami (poprzez niejawna konwersja do WrappedString wniesionego przez Szablony), więc można również wykonać następujące czynności:

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

W Scala 2,10

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

s"Hello $name, it's $weather today!" 
+1

Uważam, że jest to tylko specjalna składnia konkatenacji łańcuchów (co oznacza, że ​​$ name i $ weather są trudnymi odwołaniami do zmiennych zdefiniowanych wcześniej). String.Format jednak przyjmuje szablon jako parametr, dzięki czemu można na przykład odzyskać szablon z pliku właściwości i tym podobnych. - Czy to możliwe z powyższą składnią? – chiccodoro

+0

Jest to wywołanie interpolacji String, w scala istnieją dwa typy: s "" i f "", "s" jest prostym łańcuchem, a "f" jest podobne do 'printf', można nawet zdefiniować własną interpolację (Nie próbowałem). "$ nazwa" oznacza, że ​​należy ją zastąpić wartością zmiennej 'name', można również wykonać operację w interpolacji, na przykład' s "Hello $ {name.toUpperCase}, dzisiaj jest pogoda $ ! "' – Londo

70

Można to wykorzystać;

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

wyjściowa:

a b b c

+1

Nigdy nie widziałem tego rodzaju wykorzystania, jest to bardzo przydatne, gdy powtarzam ciąg, świetnie! –

+8

+1 to bardziej przypomina to, co używasz jako programisty języka C#. Tam używamy '{0}' i '{1}' zamiast '% 1 $' i '% 2 $'. – ashes999

+0

@ ashes999 Jestem z C# land aswell. Jestem tak przyzwyczajony do numerowanych nawiasów, o których zapomniałem, że nie był to standardowy sposób robienia rzeczy. Widząc znaki procentowe, wszystko to wraca! –

3

Jest to lista tego, co String.format może zrobić. To samo dotyczy printf

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); // |0,68| |-,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 
1

Chociaż @Londo wspomniano „S” interpolator ciąg Scala, myślę Scala "f" string interpolator jest bardziej odpowiednie do pierwotnego pytania. Przykład używany kilka czas w innych odpowiedzi można także zapisać (od Scala 2.10) w ten sposób:

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? 

Połączenie oryginalnego pytanie jest mieć świadomość, że:

  • formatted jest zdefiniowana ciąg poprzedzony literą "f". Jest to interpolator ciągów znaków "f" (formatowania).
  • „F” string interpolator wykorzystuje java.util.Formatter
  • java.lang.String.format używa tego samego java.util.Formatter

Miłą rzeczą interpolacji smyczkowy jest to, że pozwala zobaczyć, która zmienna jest podstawiona bezpośrednio do łańcucha zamiast dopasuj go do argumentów metody String.format.

0

w Scala, dla strun Interpolacja mamy $ które zapisuje dzień i uczynić nasze życie znacznie prostsze:

Dla przykładu: chcesz zdefiniować funkcję, która pobiera nazwę wejściowego oraz wiek i pozdrawia Z nazwą i mówi jej wiek. To może być napisane tak:

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

Stąd Po wywołaniu tej funkcji: tak:

funcStringInterpolationDemo("Shivansh",22) 

Jego wyjście byłoby:

Hey ! my name is Shivansh and my age is 22 

można napisać kod aby zmienić go w tej samej linii, na przykład, jeśli chcesz dodać 10 lat do wieku!

następnie funkcja może być:

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

A teraz wyjście byłoby:

Hey ! my name is Shivansh and my age is 32