首先道歉,他是Scala的初学者,我找不到这个问题的更好措辞。
我有一个属性文件,需要在其中定义一些参数化的命令(或sql查询)。以下是一个示例:
[section abc]
stage: StageA
query: Select count(*) FROM tableA WHERE account_id=${account_id} AND dt=$dt AND source=$source
[section def]
stage: StageB
query: Select count(*) FROM tableB WHERE event_date=${event_date} AND template=$template
在我的代码中,我有一个配置对象(考虑一个Map),该对象具有查询字符串(account_id
,source
,dt
,{{1 }},event_date
等)。读取属性文件后,我需要替换查询字符串中的所有宏。为此,我想编写一个具有以下签名的函数:
template
应返回查询文本,其中的宏被配置中的值替换。我尝试编写自己的String Interpolator,但是没有用。还有什么可以尝试的吗?
答案 0 :(得分:1)
通过字符串插值,编译器将String
文字切成一部分,然后再通过StringContext
发送它们进行重组。编译器不会对变量中的字符串值执行此操作,因此您必须自己剪切。
def resolve_query(query: String, config: Map[String, Any]): String =
"(.*)\\$\\{([^}]+)}(.*)".r
.findFirstMatchIn(query)
.fold(query){ m =>
resolve_query(StringContext(m.group(1), m.group(3))
.s(config.getOrElse(m.group(2), "unknown"))
,config)
}
测试:
resolve_query(
"Select count(*) FROM tableA WHERE account_id=${account_id} AND source=${source}"
,Map("account_id" -> 47, "source" -> "UK")
)
//res0: String = Select count(*) FROM tableA WHERE account_id=47 AND source=UK
您会注意到,我仅实现了更简单的${braces}
分隔表格。 $dollar
带分隔符的表单虽然没有那么复杂,但是允许两者(一个或一个或多个)的工作量比我现在愿意输入的还要多。