在Scala中更好的string格式

如果参数太多, String.format会变得太混乱。 有一个更强大的方式来格式化一个string。 像这样:

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

或者,这是不可能的,因为types的问题( format将需要采取地图[string,任何],我假设;不知道这是否会让事情变得更糟)。

或者更好的方法是这样的:

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

即使它污染名称空间?

编辑:

虽然简单的pimping可能会在很多情况下做,但我也在寻找与Python的format()相同的方向(参见: http : //docs.python.org/release/3.1.2/library/string。 html#formatstrings )

在Scala 2.10中,你可以使用string插值 。

 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 

还有一个地图的帮助正则expression式replace:

 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增强string插件文档

您可以轻松地实现更丰富的格式(使用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 

如果您使用的是2.10,则使用内置插值。 否则,如果您不关心极端的性能,也不担心function单线程,您可以使用fold +多个正则expression式扫描:

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

这是我来这里寻找的答案:

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

您也可以考虑将模板引擎用于真正复杂和长的string。 在我头顶上,我有Scalate ,其中实现了胡须模板引擎。

对于简单的string可能会过度和性能上的损失,但是你似乎在这个领域开始成为真正的模板。