string - Scala 运行时字符串插值/格式化

标签 string scala

是否有任何标准库工具可以在运行时进行字符串插值/格式化?我希望格式的行为与基于宏的 s"scala ${implementation} 完全相同,只是我的字符串格式是在运行时从配置文件加载的。

val format = config.getString("my.key")
val stringContext = parseFormat(format)
val res = stringContext.f("arg1", "arg2")

parseFormat 返回 StringContext .

我想,最坏的情况,我可以将字符串拆分为“{}”序列,并使用这些部分来构造 StringContext。

// untested
def parseFormat(format: String): StringContext =
  new StringContext("""{}""".r.split(format): _*)

我是否缺少一个明显的解决方案,或者上面的黑客可以解决问题吗?

最佳答案

没有愚蠢的问题。仅周日早上。

首先,don't use String.format .

scala> val s = "Count to %d"
s: String = Count to %d

scala> String format (s, 42)
<console>:9: error: overloaded method value format with alternatives:
  (x$1: java.util.Locale,x$2: String,x$3: Object*)String <and>
  (x$1: String,x$2: Object*)String
 cannot be applied to (String, Int)
              String format (s, 42)
                     ^

scala> s format 42
res1: String = Count to 42

但是格式化的成本可能会很高。因此,根据您选择的转义处理:

scala> StringContext("Hello, {}. Today is {}." split "\\{}" : _*).s("Bob", "Tuesday")
res2: String = Hello, Bob. Today is Tuesday.

scala> StringContext("""Hello, \"{}.\" Today is {}.""" split "\\{}" : _*).s("Bob", "Tuesday")
res3: String = Hello, "Bob." Today is Tuesday.

scala> StringContext("""Hello, \"{}.\" Today is {}.""" split "\\{}" : _*).raw("Bob", "Tuesday")
res4: String = Hello, \"Bob.\" Today is Tuesday.

事实证明 split 并不能完全破解它。

scala> StringContext("Count to {}" split "\\{}" : _*) s 42
java.lang.IllegalArgumentException: wrong number of arguments (1) for interpolated string with 1 parts
  at scala.StringContext.checkLengths(StringContext.scala:65)
  at scala.StringContext.standardInterpolator(StringContext.scala:121)
  at scala.StringContext.s(StringContext.scala:94)
  ... 33 elided

既然如此

scala> val r = "\\{}".r
r: scala.util.matching.Regex = \{}

scala> def parts(s: String) = r split s
parts: (s: String)Array[String]

也许

scala> def f(parts: Seq[String], args: Any*) = (parts zip args map (p => p._1 + p._2)).mkString
f: (parts: Seq[String], args: Any*)String

所以

scala> val count = parts("Count to {}")
count: Array[String] = Array("Count to ")

scala> f(count, 42)
res7: String = Count to 42

scala> f(parts("Hello, {}. Today is {}."), "Bob", "Tuesday")
res8: String = Hello, Bob. Today is Tuesday

嘿,等等!

scala> def f(parts: Seq[String], args: Any*) = (parts.zipAll(args, "", "") map (p => p._1 + p._2)).mkString
f: (parts: Seq[String], args: Any*)String

scala> f(parts("Hello, {}. Today is {}."), "Bob", "Tuesday")
res9: String = Hello, Bob. Today is Tuesday.

scala> def f(parts: Seq[String], args: Any*) = (for (i <- 0 until (parts.size max args.size)) yield (parts.applyOrElse(i, (_: Int) => "") + args.applyOrElse(i, (_: Int) => ""))).mkString
f: (parts: Seq[String], args: Any*)String

scala> def f(parts: Seq[String], args: Any*) = { val sb = new StringBuilder ; for (i <- 0 until (parts.size max args.size) ; ss <- List(parts, args)) { sb append ss.applyOrElse(i, (_: Int) => "") } ; sb.toString }
f: (parts: Seq[String], args: Any*)String

scala> f(parts("Hello, {}. Today is {}. {}"), "Bob", "Tuesday", "Bye!")
res16: String = Hello, Bob. Today is Tuesday. Bye!

关于string - Scala 运行时字符串插值/格式化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22643036/

相关文章:

scala - WARN ScalaRowValueReader:字段 'client'由数组支持,但是关联的Spark Schema不能反射(reflect)这一点

c - C 中的正则表达式自定义替换函数

user-interface - 是否有用于在Scala中创建GUI的GUI?

java - 无法使用反斜杠读取属性文件

java - 如何获取由原始字符串保留顺序的所有唯一字符组成的字符串?

ScalaCheck,调用 Test.check 或 Test.checkProperties 时的不同行为

postgresql - scala中的Postgres JDBC无法在不重新启动sbt的情况下运行两个查询

swift - 与 Swift 的 ScalaCheck 等效吗? (测试数据生成器框架)

javascript - 提取括号之间的字符串

java - 在 Java 中遵循 if-else 阶梯的更好选择是什么?