Regex Scala正则表达式分析器抛出奇怪的错误

Regex Scala正则表达式分析器抛出奇怪的错误,regex,scala,parsing,Regex,Scala,Parsing,我有一个简单的RegexParser,它匹配{key}={value}多次重复: object CommandOptionsParser extends RegexParsers { private val key: Parser[String] = "[^= ]+".r private val value: Parser[String] = "[^ ]*".r val pair: Parser[Option[(String, Option[String])]] = (ke

我有一个简单的RegexParser,它匹配{key}={value}多次重复:

object CommandOptionsParser extends RegexParsers {
  private val key: Parser[String] = "[^= ]+".r
  private val value: Parser[String] = "[^ ]*".r

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

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

  def apply(input: String): Map[String, Option[String]] = parseAll(pairs, input) match {
    case Success(plan, _) => plan
    case x => sys.error(x.toString)
  }
}
然而,在超过1个捕获组上,值的匹配似乎失败(尽管正则表达式没有限制它)。当我尝试匹配“token=abc再次=abc”时,我有以下错误:

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

token=abc again=abc'
          ^

为什么RegexParser会有如此奇怪的行为?

修复您的意外行为非常简单,只需更改
skipWhitespace的值即可:

object CommandOptionsParser extends RegexParsers {
  override val skipWhitespace = false
RegexParsers
的描述中:

解析方法调用方法
skipWhitespace
(默认为
true
),如果为true,则在创建每个解析器之前跳过任何空格 打电话来

因此,发生了什么,您的第一个
被匹配,然后跳过了
空白
,然后,由于
repsep
找不到另一个空白分隔符,它只是假设解析已经结束,因此需要“\z”

另外,我不得不注意到,用于这种简单任务的整个解析器方法似乎过于复杂,简单的regexp就足够了


UPD:您的解析器也可以更简单一些:

  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: _*)}