2

示例上下文:

具有如下正文的 HTTP 响应:

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

键的名称始终是已知的。

目前提取是用正则表达式完成的:

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

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

4

3 回答 3

5

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

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

val response = "key1=val1&key2=val2&key3=val3"
val params = (for { x <- response split ("&")
                    Array(k, v) = x split ("=") }
                yield k->v).toMap
于 2013-09-16T15:51:07.723 回答
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)
}
于 2013-09-16T12:34:45.100 回答
3

您可以像这样使用正则表达式作为匹配器:

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

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

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

response split ("&") map (toKv) 
于 2013-09-16T11:23:44.410 回答