Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing 轻松地将Key=Value对的字符串解析为Scala case类_Parsing_Scala_Key Value_Case Class - Fatal编程技术网

Parsing 轻松地将Key=Value对的字符串解析为Scala case类

Parsing 轻松地将Key=Value对的字符串解析为Scala case类,parsing,scala,key-value,case-class,Parsing,Scala,Key Value,Case Class,有什么方法可以轻松地将一串键值对解析为scala case类 例如,从以下字符串: "consumer_key=1234ABC, consumer_secret=12345ABC" 进入 您可以使用正则表达式和模式匹配: scala> val R = "consumer_key=(.*), consumer_secret=(.*)".r R: scala.util.matching.Regex = consumer_key=(.*), consumer_secret=(.*) scal

有什么方法可以轻松地将一串键值对解析为scala case类

例如,从以下字符串:

"consumer_key=1234ABC, consumer_secret=12345ABC"
进入


您可以使用正则表达式和模式匹配:

scala> val R = "consumer_key=(.*), consumer_secret=(.*)".r
R: scala.util.matching.Regex = consumer_key=(.*), consumer_secret=(.*)

scala> "consumer_key=1234ABC, consumer_secret=12345ABC" match {
     |   case R(k, v) => Auth(k, v)
     | }
res0: Auth = Auth(1234ABC,12345ABC)
使用
JavaTokenParsers
进行更灵活的解析:

import scala.util.parsing.combinator._

case class Auth( consumerKey: String, consumerSecret: Option[String])

class AuthParser extends JavaTokenParsers {
  def auth: Parser[Auth] = key ~ opt("," ~> secret) ^^ { case k ~ s => Auth(k, s)}
  def key: Parser[String] = value("consumer_key")
  def secret: Parser[String] = value("consumer_secret")
  def value(k: String): Parser[String] = k ~ "=" ~> "[^,]*".r
  def apply(s: String) = parseAll(auth, s)
}
用法:

scala> val p = new AuthParser
p: AuthParser = AuthParser@433b9799

scala> p("consumer_key=1234ABC, consumer_secret=12345ABC").get
res0: Auth = Auth(1234ABC,Some(12345ABC))

scala> p("consumer_key=1234ABC").get
res1: Auth = Auth(1234ABC,None)

我喜欢scala解析器库,但它有点慢。如果您的字符串都是这样的,您也可以轻松地执行以下操作:

case class Auth( consumerKey:String, consumerSecret:String)
object Auth {
  def fromString(string: String): Seq[Auth] = string.split(", ").toSeq map { pair =>
    val lst = pair.split("=")
    Auth(lst(0), lst(1))
  }
}

我同意nnythm,但该解决方案无法解决问题。这可能会更好:

case class Auth( consumerKey:String, consumerSecret:String)
object Auth {
  def fromString(s: String): Auth = {
    val p = s.split(", ").toSeq.map { pair => {
        val lst = pair.split("=")
        (lst(0), lst(1))
    }}.toMap
    Auth(p("consumer_key"), p("consumer_secret"))
  }
}

这样做的另一个好处是,可以拥有一个包含任意数量键值对的字符串,并且您可以轻松地更改选择使用的字符串。

Scala 2.13
开始,如果您期望的模式足够简单,则可以通过以下方式进行模式匹配:


你所有的字符串都是这种结构吗?如果是这样,为什么不明确地打破它
val(key,secret)=(s.slice(“consumer_key=”.length,s.indexOf(“,”),s.drop(s.lastIndexOf(“=”))
没有,我刚刚发布了前两个,但还有更多。谢谢这就是我一直在寻找的,有没有办法让其中一个成为可选的?@AnthonyMcCormick:optional
consumer_secret
的答案更新。
case class Auth( consumerKey:String, consumerSecret:String)
object Auth {
  def fromString(s: String): Auth = {
    val p = s.split(", ").toSeq.map { pair => {
        val lst = pair.split("=")
        (lst(0), lst(1))
    }}.toMap
    Auth(p("consumer_key"), p("consumer_secret"))
  }
}
// case class Auth(consumerKey: String, consumerSecret: String)
"consumer_key=1234ABC, consumer_secret=12345ABC" match {
  case s"consumer_key=$key, consumer_secret=$secret" => Auth(key, secret)
}
// Auth("1234ABC", "12345ABC")