2012-10-25 28 views
5

Có cách nào dễ dàng phân tích cú pháp một chuỗi các cặp giá trị khóa thành một lớp scala case không?Dễ dàng phân tích cú pháp Chuỗi khóa = Cặp giá trị cho lớp chữ Scala

ví dụ từ các chuỗi sau

"consumer_key=1234ABC, consumer_secret=12345ABC" 

vào

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

hoặc thậm chí

case class Auth(consumer_key:String, consumer_secret:String) 
+0

là tất cả các chuỗi của bạn đều có cấu trúc này? nếu vậy, tại sao bạn không phá vỡ nó một cách rõ ràng? 'val (khóa, bí mật) = (s.slice (" consumer_key = ". length, s.indexOf (", ")), s.drop (s.lastIndexOf (" = ")))' –

+0

Không, tôi vừa mới đăng hai cái đầu tiên nhưng có nhiều hơn. –

Trả lời

9

Bạn có thể sử dụng regex và khớp mẫu:

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) 

Sử dụng JavaTokenParsers cho phân tích cú pháp linh hoạt hơn:

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

Cách sử dụng:

scala> val p = new AuthParser 
p: AuthParser = [email protected] 

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) 
+0

Cảm ơn thats những gì tôi đang tìm kiếm, Có anyway để làm cho một trong số họ tùy chọn? –

+0

@AnthonyMcCormick: câu trả lời được cập nhật cho 'consumer_secret' tùy chọn. – senia

2

Tôi yêu thư viện parsers scala, nhưng nó là một chút chậm. Nếu tất cả các chuỗi của bạn trông giống như vậy, bạn có thể dễ dàng làm như vậy:

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

Tôi đồng ý với nythm nhưng giải pháp đó không giải quyết được vấn đề. Điều này có thể hoạt động tốt hơn:

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

Điều này có thêm lợi ích khi có thể có chuỗi với bất kỳ số cặp khóa giá trị nào và bạn có thể dễ dàng thay đổi bạn chọn làm việc.

Các vấn đề liên quan