Лучшее форматирование строк в Scala



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



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


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



или это лучший способ сделать это так:



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


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



Edit:



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

712   7  

7 ответов:

в 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

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

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

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

Scala-Enhanced-Strings-Plugin Documentation

вы можете легко реализовать более богатое форматирование самостоятельно (с подходом 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

этот ответ я пришел сюда в поисках:

"This is %s string".format(1)

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

val template = "Hello #{name}!"
val replacements = Map( "name" -> "Aldo" )
replacements.foldLeft(template)((s:String, x:(String,String)) => ( "#\{" + x._1 + "\}" ).r.replaceAllIn( s, x._2 ))

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

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

Comments

    Ничего не найдено.