将字符串转换为列表列表

时间:2019-11-07 11:06:57

标签: scala parsing

输入(字符串):

[[0_busswvan, 24.0, 2019-09-05 20:15:33],[05f9acb08d7c11e89e8fede614b72917, 20.0, 2019-09-05 14:06:32], [0_h2qbu9h3, 28.0, 2019-09-05 14:01:20],[2_busswvan, 24.0, 2019-09-05 20:15:33],[05f9acb08d7c11e89e8fede614b72917, 25.0, 2019-08-12 14:06:32], [1442qbu9h3, 28.0, 2019-09-05 14:01:20]]

我想将此字符串转换为类型为List[List[String,Double,String]]

的列表的列表

最好的方法是什么?

到目前为止,我已经尝试过:

var a : String = "[[0_busswvan, 24.0, 2019-09-05 20:15:33], [05f9acb08d7c11e89e8fede614b72917, 20.0, 2019-09-05 14:06:32], [0_h2qbu9h3, 28.0, 2019-09-05 14:01:20]]" 
var b : String = "[[2_busswvan, 24.0, 2019-09-05 20:15:33],[05f9acb08d7c11e89e8fede614b72917, 25.0, 2019-08-12 14:06:32], [1442qbu9h3, 28.0, 2019-09-05 14:01:20]]" 
a = a.substring(2,a.length-1).concat(",") 
b = b.substring(1,b.length-2) 
var res = a.concat(b) 
var res1 = res.split("\\] ?, ?\\[").map(List(_):List[Any]).toList

但是问题在于它的类型:List[List[String]]

2 个答案:

答案 0 :(得分:1)

唯一的小错误是您使用map而不是flatMap

这按预期工作:

 var res1 = res.split("\\] ?, ?\\[").flatMap(List(_):List[Any]).toList

如果您对此感兴趣,可以通过以下答案来解释差异:https://stackoverflow.com/a/45319928/2750966

另一种方法是最后flatten

var res1 = res.split("\\] ?, ?\\[").map(List(_):List[Any]).toList.flatten

答案 1 :(得分:1)

或者,对于pme的解决方案,您可以尝试使用parser combinators module

首先,由于其他功能已移至单独的模块,因此您需要将其添加为依赖项:

public class Component<T> wher T:IComponent { void Load(T component) {} }

然后您可以准备解析器:

libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.2"

您的方法还有一个问题,当您使用import java.time.format.DateTimeFormatter; import java.time._ import scala.util.parsing.combinator._ val r = "[[0_busswvan, 24.0, 2019-09-05 20:15:33],[05f9acb08d7c11e89e8fede614b72917, 20.0, 2019-09-05 14:06:32], [0_h2qbu9h3, 28.0, 2019-09-05 14:01:20],[2_busswvan, 24.0, 2019-09-05 20:15:33],[05f9acb08d7c11e89e8fede614b72917, 25.0, 2019-08-12 14:06:32], [1442qbu9h3, 28.0, 2019-09-05 14:01:20]]" object Parser extends RegexParsers { val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") def text: Parser[String] = """\w+""".r //parser for text def number: Parser[Double] = """\d+(\.\d*)?""".r ^^ { _.toDouble } //parser for numbers def datetime: Parser[LocalDateTime] = """\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}""".r ^^ { p => LocalDateTime.from(formatter.parse(p)) } //parser for date def glue: Parser[String] = """\w*,\w*""".r //parser for comma separators def term : Parser[List[Any]] = "[" ~ text ~ ", " ~ number ~ ", " ~ datetime ~ "]" ~ opt(glue) ^^ { //parser for matching whole sublist case _ ~ text ~ _ ~ number ~ _ ~ datetime ~ _ ~ _ => { List(text, number, datetime) } } def expr : Parser[List[List[Any]]] = "[" ~> rep(term) <~ "]" //parser for whole list containing arbitrary number of sublist def apply(input: String): List[Any] = parseAll(expr, input) match { case Success(result, _) => result case failure : NoSuccess => scala.sys.error(failure.msg) } } println(Parser(r)) //List(List(0_busswvan, 24.0, 2019-09-05T20:15:33), List(05f9acb08d7c11e89e8fede614b72917, 20.0, 2019-09-05T14:06:32), List(0_h2qbu9h3, 28.0, 2019-09-05T14:01:20), List(2_busswvan, 24.0, 2019-09-05T20:15:33), List(05f9acb08d7c11e89e8fede614b72917, 25.0, 2019-08-12T14:06:32), List(1442qbu9h3, 28.0, 2019-09-05T14:01:20)) 存储Double,String和LocalDateTime的值时,编译器会将列表的类型扩展为List。您可以考虑改用元组List[Any]。在这种情况下,解析器将变为:

(String, Double, LocalDateTime)