String Scala中更好的字符串格式

String Scala中更好的字符串格式,string,scala,formatting,string-formatting,String,Scala,Formatting,String Formatting,由于参数太多,String.format很容易变得太混乱。是否有更强大的方法格式化字符串。像这样: "This is #{number} string".format("number" -> 1) 或者这是因为类型问题而不可能的(格式需要一个Map[String,Any],我想;不知道这是否会让事情变得更糟) 还是这样做更好: val number = 1 <plain>This is { number } string</plain> text val num

由于参数太多,
String.format
很容易变得太混乱。是否有更强大的方法格式化字符串。像这样:

"This is #{number} string".format("number" -> 1)
或者这是因为类型问题而不可能的(
格式
需要一个Map[String,Any],我想;不知道这是否会让事情变得更糟)

还是这样做更好:

val number = 1
<plain>This is { number } string</plain> text
val number=1
这是{number}字符串文本
即使它污染了名字空间

编辑:


虽然简单的pimp在很多情况下都可以实现,但我也在寻找与Python的
format()
(请参阅:)

相同的方法(使用pimp my library方法),您可以轻松实现更丰富的格式设置:


也许Scala增强的字符串插件可以帮助您。看这里:


如果您唯一的问题是使参数的顺序更灵活,那么这很容易做到:

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>val map=map(“数字”->1)
map:scala.collection.immutable.map[java.lang.String,Int]=map((数字,1))
scala>val getGroup=(93;:scala.util.matching.Regex.Match)组1
getGroup:(util.matching.Regex.Match)=>String=
scala>val pf=getGroup和then map.lift和then(u-map(u.toString))
pf:(util.matching.Regex.Match)=>Option[java.lang.String]=
scala>val pat=“\\\{([^}]*)\\}”.r
pat:scala.util.matching.Regex=\\{([^}]*)\}
scala>patreplacesomein(“这是#{number}字符串”,pf)
res43:String=这是一个字符串
在Scala 2.10中,您可以使用


如果您使用的是2.10,则使用内置插值。否则,如果您不关心极端性能,也不害怕功能性的一行程序,则可以使用折叠+多个regexp扫描:

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)

是的,我甚至可以使用
%
来实现这一点(就像在其他一些语言中一样)。不过,它可能会更强大一些……(可能像python的格式一样)看起来很有趣。(docu和插件都有。)但还是有点疯狂(两者都有),因为语法有时不使用任何分隔符……我在生产中使用它,它很棒!仅当要插入的表达式的语法远远超出了变量名时,才需要分隔符。对于2.10+用户,请务必查看位于的内置字符串插入。感谢Andrej指出了这一点。FWIW,我不同意人们需要处于
String.format
有太多参数的情况。使用两个或更多字符串;使用
+
进行连接。当然,如果有人愿意花时间为那些喜欢python格式而不是C格式的人克隆python格式,那就太好了。当然,应用程序并不多,但有时候你只想外部化一个模板字符串,这样的优势在我看来是显而易见的。或者对于国际化的东西(虽然我不知道Python格式是否足够强大)。但是Java不应该已经有这样的东西吗?@总是问(via):当这个问题发布时,这些标签可能不存在;尽管如此,这一添加还是有意义的。
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)