使用Scala中的占位符替换字符串中的值

时间:2010-02-02 11:12:27

标签: scala functional-programming

我刚开始使用Scala并希望更好地理解解决问题的功能方法。 我有一对字符串,第一个字符串有参数的占位符,它的对具有要替换的值。例如 “从tab1中选择col1,其中id> $ 1,名称为$ 2” “参数:$ 1 ='250',$ 2 ='some%'”

可能有超过2个参数。

我可以通过逐步执行并在每一行上使用regex.findAllIn(line)构建正确的字符串,然后通过迭代器来构造替换,但这似乎相当不优雅且程序驱动。

有人能指出一种更整洁,更不容易出错的功能性方法吗?

5 个答案:

答案 0 :(得分:29)

答案 1 :(得分:14)

您可以使用standard Java String.format style扭曲:

"My name is %s and I am %d years of age".format("Oxbow", 34)

在Java当然这看起来像:

String.format("My name is %s and I am %d years of age", "Oxbow", 34)

这两种样式之间的主要区别(我更喜欢Scala)是概念上这意味着每个String都可以被认为是Scala中的格式字符串(即格式方法似乎是一个实例方法在String班上。虽然这可能被认为在概念上是错误的,但它会导致更直观和可读的代码。

这种格式化样式允许您根据需要格式化浮点数,日期等。它的主要问题是格式字符串中的占位符与参数之间的“绑定”纯粹是基于顺序的,与之无关以任何方式命名(如"My name is ${name}")虽然我没有看到......

interpolate("My name is ${name} and I am ${age} years of age", 
               Map("name" -> "Oxbow", "age" -> 34))

...在我的代码中嵌入了更多可读性。这种东西对于文本替换更有用,其中源文本嵌入在单独的文件中(例如 i18n ),您可能需要这样的文件:

"name.age.intro".text.replacing("name" as "Oxbow").replacing("age" as "34").text

或者:

"My name is ${name} and I am ${age} years of age"
     .replacing("name" as "Oxbow").replacing("age" as "34").text

我认为这很容易使用,只需几分钟即可完成(我似乎无法使用我的Scala 2.8版本编译Daniel的插值):

object TextBinder {
  val p = new java.util.Properties
  p.load(new FileInputStream("C:/mytext.properties"))

  class Replacer(val text: String) {
    def replacing(repl: Replacement) = new Replacer(interpolate(text, repl.map))
  }

  class Replacement(from: String, to: String) {
    def map = Map(from -> to)
  }
  implicit def stringToreplacementstr(from: String) = new {
    def as(to: String) = new Replacement(from, to)
    def text = p.getProperty(from)
    def replacing(repl: Replacement) = new Replacer(from)
  }

  def interpolate(text: String, vars: Map[String, String]) = 
    (text /: vars) { (t, kv) => t.replace("${"+kv._1+"}", kv._2)  }
}

顺便说一句,我是一个流畅的API的傻瓜!不管他们有多么无形!

答案 2 :(得分:3)

这不是你问题的直接答案,而是更多Scala技巧。您可以使用xml:

在Scala中插入字符串
val id = 250
val value = "some%"
<s>select col1 from tab1 where id > {id} and name like {value}</s>.text
// res1: String = select col1 from tab1 where id > 250 and name like some%

埃里克。

答案 3 :(得分:1)

您可以使用鲜为人知的“QP括号”来分隔字符串中的scala表达式。这比其他方法更有优势,因为您可以使用任何scala表达式,而不仅仅是简单的vals / vars。只需使用开头"+并关闭+"括号分隔符。

示例:

  val name = "Joe Schmoe"
  val age = 32
  val str = "My name is "+name+" and my age is "+age+"."

答案 4 :(得分:1)

Scala 2.10 introduces syntax for making string interpolation simpler.

for (i <- 0 to 10)
    println(s"iteration: $i")