提取已知密钥的惯用方法 - >来自字符串的val对

时间:2013-09-16 10:27:49

标签: scala

示例上下文:

具有正文的HTTP响应如下:

key1=val1&key2=val2&key3=val3.

密钥的名称始终是已知的。

目前使用正则表达式进行提取:

  val params = response split ("""&""") map { _.split("""=""") } map { el => { el(0) -> el(1) } } toMap;

是否有更简单的模式匹配特定参数的响应?

3 个答案:

答案 0 :(得分:5)

我认为使用split可能是最快/最简单的解决方案。您没有进行任何高级解析,因此使用解析器组合器或正则表达式捕获组似乎有点矫枉过正。

但是,当您的复杂表达式涉及多次调用mapfilter等时,它通常表明您可以通过理解来清理事物:< / p>

val response = "key1=val1&key2=val2&key3=val3"
val params = (for { x <- response split ("&")
                    Array(k, v) = x split ("=") }
                yield k->v).toMap

答案 1 :(得分:4)

您可以在此处使用解析器组合器以获得最大的灵活性和健壮性(即处理失败的解析):

object Parser extends RegexParsers with App {
  def lit: Parser[String] = "[^=&]+".r

  def pair: Parser[(String, String)] = lit ~ "=" ~ lit ^^ {
    case key ~ "=" ~ value => key -> value
  }

  def parse: Parser[Seq[(String, String)]] = repsep(pair, "&")

  val response = "key1=val1&key2=val2&key3=val3"
  val params = parse(new CharSequenceReader(response)).get.toMap
  println(params)
}

答案 2 :(得分:3)

您可以使用regexp作为匹配器:

val r = "([^=]+)=([^=]+)".r

 def toKv(s:String) = s match { 
    case r(k,v) => (k,v)
    case _ => throw InvalidFormatException
}

因此,对于您的情况,它看起来像:

response split ("&") map (toKv)