假设我有以下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 号码而无法继续下一个。
答案 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
键的值