将所有解析结果保存到scala中的一个映射中

时间:2015-04-28 13:45:23

标签: scala parsing

假设我有以下txt文件:

--quest_29540602496284069
Operator Name : Kevin
Account Id: 1444

Text: This is Kevin and this my text.
Age: 16
--quest_=29540602496284069--

我想将其转换为简单的scala地图:

(pseudo-code)
{
  quest_id: 29540602496284069
  operation_name = Kevin 
  account_id: 1444
  text: This is Kevin and this my text.
  operator_age: 16
}

因此,我开始创建案例内容类,以便将其存储在目标对象中以供将来使用:

case class MapContent(map: Map[String, String])

然后,我创建了扩展RegexpParsers的scala类:

class OperatorParser extends RegexParsers {

  def parseFullRequest(input: String): MapContent = parseAll(parseRequest, input) match {
    case Success(result, _) => result
    case NoSuccess(msg, _) => throw new SomeParserException(msg)
  }

  // main entry
  def parseRequest: Parser[MapContent] = parseQuestBody ~ parseAnotherBody

  def parseQuestBody: Parser[MapContent] = parseQuestId

  def parseQuestId: Parser[MapContent] = "--quest_" ~> """.+\n?""".r ^^ { case res =>
    MapContent(Map("quest_id" -> res.toString))
  }

  def parseAnotherBody: Parser[MapContent] = """.+""".r ^^ { case res =>
    MapContent(Map("another_body" -> res.toString))
  }

}

当我在做

parseQuestBody ~ parseAnotherBody

导致运算符[MapContent,MapContent]不是运算符[MapContent]

的错误

我需要一个解决方案,如何在整个解析过程中准确地存储在MapContent中。有可能这样做吗?目前我只能存储 quest_id 号码而无法继续下一个。

1 个答案:

答案 0 :(得分:1)

您可以像其他解析器一样使用^^

def parseRequest: Parser[MapContent] = parseQuestBody ~ parseAnotherBody ^^ {
    case res => MapContent(res._1.map ++ res._2.map)
}

def parseRequest: Parser[MapContent] = parseQuestBody ~ parseAnotherBody ^^ {
    case a ~ b => MapContent(a.map ++ b.map)
}

它将MapContents的“元组”转换为单MapContent

编辑:

  

如果我将拥有大量文本值,那么在scala中它将是   看起来像a.map ++ b.map ++ c.map ++ d ... + f .. + ... + x1?是   有更常见的方式吗?

折叠它是一种可能性:

def parseRequest: Parser[MapContent] = parseQuestId ~ rep(parseAnotherBody) ~ parseQuestId ^^ {
    case value1 ~ list1 ~ value2=> {
      val merged = List(value1, value2) ++ list1
      merged.foldLeft(MapContent(Map.empty[String, String]))((a, b) => MapContent(a.map ++ b.map))
    }
  }

它返回仅包含2个值的地图,因为您无法在地图2中存储具有相同another_body键的值