2016-04-11 30 views
1

Ben birkaç kez tekrarlayarak {anahtarı} = {değer} eşleşen basit RegexParser var atar Buna rağmen regex onu sınırlandırmaz). Ben "belirteç = abc again = abc" karşı maç çalıştığınızda, aşağıdaki hata var:Scala Regex Ayrıştırıcı garip hata

[1.11] failure: string matching regex `\z' expected but `a' found 

token=abc again=abc' 
     ^

RegexParser böyle garip davranışları vardır Neden?

sizin beklenmeyen davranışlar için düzeltme oldukça kolaydır

cevap

1

, sadece skipWhitespace değerini değiştirin:

object CommandOptionsParser extends RegexParsers { 
    override val skipWhitespace = false 

açıklamasından RegexParsers ait: Yani

The parsing methods call the method skipWhitespace (defaults to true) and, if true, skip any whitespace before each parser is called.

, ne oldu, ilk pair eşleştirildi daha sonra whiteSpace atlandı ve daha sonra repsep başka bir boşluk boşluk ayırıcısı bulamadığı için, yalnızca ayrıştırma işleminin bittiğini, dolayısıyla "\ z" nin beklendiğini varsaydı.

Ayrıca, yardımcı olamıyorum, ancak böylesine basit bir görev için tüm Ayrıştırıcı yaklaşımının aşırı karmaşık, basit düzenli ifadelerin yeterli olacağına dikkat edin.


UPD: Ayrıca ayrıştırıcıları biraz daha basit olabilir:

val pair: Parser[Option[(String, Option[String])]] = 
    (key ~ ("=" ~> value).?).? ^^ (_.map {case (k ~ v) => k.trim -> v.map(_.trim)}) 

    val pairs: Parser[Map[String, Option[String]]] = phrase(repsep(pair, whiteSpace)) ^^ 
    { l => Map(l.flatten: _*)}