重写字符串修改更实用

Kaj*_*Abt 5 scala

我正在读取文件中的行

for (line <- Source.fromFile("test.txt").getLines) {
  ....
}
Run Code Online (Sandbox Code Playgroud)

我基本上想要最后得到一个段落列表.如果一行为空,则以新段落开头,我可能希望将来解析一些关键字 - 值对.

文本文件包含这样的条目列表(或类似的东西,如Ini文件)

User=Hans
Project=Blow up the moon
The slugs are going to eat the mustard. // multiline possible!
They are sneaky bastards, those slugs. 

User=....
Run Code Online (Sandbox Code Playgroud)

我基本上想要一个List [Project] Project看起来像

class Project (val User: String, val Name:String, val Desc: String) {}
Run Code Online (Sandbox Code Playgroud)

而描述是大块的文本,不是以a开头<keyword>=,而是可以延伸到任意数量的行.

我知道如何以迭代的方式做到这一点.只需对关键字进行检查列表,然后填充类的实例,并将其添加到列表中以便稍后返回.

但我认为应该可以以适当的函数样式执行此操作,可能使用match case, yield和递归,从而生成包含字段的对象列表User,Project依此类推.使用的类是已知的,所有关键字都是已知的,并且文件格式也不是一成不变的.我主要是想学习更好的功能风格.

the*_*mel 8

你显然正在解析一些东西,所以可能是时候使用......一个解析器了!

由于您的语言似乎将换行视为重要,因此您需要参考此问题来告诉解析器.

除此之外,一个相当简单的实现

import scala.util.parsing.combinator.RegexParsers

case class Project(user: String, name: String, description: String)

object ProjectParser extends RegexParsers {
  override val whiteSpace = """[ \t]+""".r

  def eol : Parser[String] = """\r?\n""".r

  def user: Parser[String] = "User=" ~> """[^\n]*""".r <~ eol
  def name: Parser[String] = "Project=" ~> """[^\n]*""".r <~ eol
  def description: Parser[String] = repsep("""[^\n]+""".r, eol) ^^ { case l => l.mkString("\n") }
  def project: Parser[Project] = user ~ name ~ description ^^ { case a ~ b ~ c => Project(a, b, c) }
  def projects: Parser[List[Project]] = repsep(project,eol ~ eol)
}
Run Code Online (Sandbox Code Playgroud)

以及如何使用它:

val sample = """User=foo1
Project=bar1
desc1
desc2
desc3

User=foo
Project=bar
desc4 desc5 desc6
desc7 desc8 desc9"""

import scala.util.parsing.input._
val reader = new CharSequenceReader(sample)
val res = ProjectParser.parseAll(ProjectParser.projects, reader)
if(res.successful) {
    print("Found projects: " + res.get)
} else {
    print(res)
}
Run Code Online (Sandbox Code Playgroud)