Search code examples
parsingscalakey-valuecase-class

Easily parse String of Key=Value pairs to Scala case class


Is there any way to easily parse a string of key value pairs into a scala case class?

For example from the following string:

"consumer_key=1234ABC, consumer_secret=12345ABC"

into

case class Auth(consumerKey: String, consumerSecret: String)

Solution

  • You can use regex and pattern matching:

    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)
    

    Use JavaTokenParsers for more flexible parsing:

    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)
    }
    

    Usage:

    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)