Лучшее форматирование строк в Scala - PullRequest
55 голосов
/ 29 октября 2010

При слишком большом количестве аргументов String.format легко запутывается. Есть ли более мощный способ форматирования строки. Вот так:

"This is #{number} string".format("number" -> 1)

Или это невозможно из-за проблем с типами (я полагаю, format потребуется взять карту [String, Any]; не знаю, ухудшит ли это положение).

Или лучше сделать это так:

val number = 1
<plain>This is { number } string</plain> text

даже если оно загрязняет пространство имен?

Изменить:

Несмотря на то, что во многих случаях возможно простое сутенерство, я также ищу что-то, идущее в том же направлении, что и format() в Python (см .: http://docs.python.org/release/3.1.2/library/string.html#formatstrings)

Ответы [ 7 ]

71 голосов
/ 21 ноября 2012

В Scala 2.10 вы можете использовать строковую интерполяцию .

val height = 1.9d
val name = "James"
println(f"$name%s is $height%2.2f meters tall")  // James is 1.90 meters tall
38 голосов
/ 30 октября 2010

Ну, если ваша единственная проблема - сделать порядок параметров более гибким, это легко сделать:

scala> "%d %d" format (1, 2)
res0: String = 1 2

scala> "%2$d %1$d" format (1, 2)
res1: String = 2 1

И есть также замена регулярных выражений с помощью карты:

scala> val map = Map("number" -> 1)
map: scala.collection.immutable.Map[java.lang.String,Int] = Map((number,1))

scala> val getGroup = (_: scala.util.matching.Regex.Match) group 1
getGroup: (util.matching.Regex.Match) => String = <function1>

scala> val pf = getGroup andThen map.lift andThen (_ map (_.toString))
pf: (util.matching.Regex.Match) => Option[java.lang.String] = <function1>

scala> val pat = "#\\{([^}]*)\\}".r
pat: scala.util.matching.Regex = #\{([^}]*)\}

scala> pat replaceSomeIn ("This is #{number} string", pf)
res43: String = This is 1 string
17 голосов
/ 29 октября 2010

Может быть, Scala-Enhanced-Strings-Plugin может вам помочь. Смотрите здесь:

Документация по Scala-Enhanced-Strings-Plugin

14 голосов
/ 29 октября 2010

Вы можете легко реализовать более богатое форматирование самостоятельно (с помощью подхода pimp-my-library):

scala> implicit def RichFormatter(string: String) = new {
     |   def richFormat(replacement: Map[String, Any]) =
     |     (string /: replacement) {(res, entry) => res.replaceAll("#\\{%s\\}".format(entry._1), entry._2.toString)}
     | }
RichFormatter: (string: String)java.lang.Object{def richFormat(replacement: Map[String,Any]): String}

scala> "This is #{number} string" richFormat Map("number" -> 1)
res43: String = This is 1 string
9 голосов
/ 08 октября 2015

Это ответ, который я пришел сюда в поисках:

"This is %s string".format(1)
4 голосов
/ 02 января 2013

Если вы используете 2.10, тогда используйте встроенную интерполяцию.В противном случае, если вы не заботитесь об экстремальной производительности и не боитесь функциональных однострочников, вы можете использовать фолд + несколько сканирований регулярного выражения:

val template = "Hello #{name}!"
val replacements = Map( "name" -> "Aldo" )
replacements.foldLeft(template)((s:String, x:(String,String)) => ( "#\\{" + x._1 + "\\}" ).r.replaceAllIn( s, x._2 ))
2 голосов
/ 12 марта 2014

Вы также можете рассмотреть использование шаблонизатора для действительно сложных и длинных строк.В верхней части головы у меня есть Scalate , в котором реализован, помимо прочего, шаблонизатор Усы .

Может быть излишним и потеря производительности для простых строк, но вы, кажется, находитесь в той области, где они начинают становиться реальными шаблонами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...