gpt4 book ai didi

regex - 使用解析器组合器整理文本行

转载 作者:行者123 更新时间:2023-12-01 09:28:14 25 4
gpt4 key购买 nike

我正在尝试使用解析器组合器解析文本文件。我想在名为 Example 的类中捕获索引和文本。这是在输入文件上显示表单的测试:

object Test extends ParsComb with App {
val input = """
0)
blah1
blah2
blah3
1)
blah4
blah5
END
"""
println(parseAll(examples, input))
}

这是我的尝试,但没有成功:

import scala.util.parsing.combinator.RegexParsers

case class Example(index: Int, text: String)

class ParsComb extends RegexParsers {
def examples: Parser[List[Example]] = rep(divider~example) ^^
{_ map {case d ~ e => Example(d,e)}}
def divider: Parser[Int] = "[0-9]+".r <~ ")" ^^ (_.toInt)
def example: Parser[String] = ".*".r <~ (divider | "END")
}

它失败了:

[4.1] failure: `END' expected but `b' found

blah2

^

我刚开始使用这些,所以我不太清楚自己在做什么。我认为问题可能出在 ".*".r 正则表达式不支持多行。我该如何更改它才能正确解析?

最佳答案

  • 错误信息是什么意思?

根据你的语法定义,".*".r <~ (divider | "END") ,你告诉解析器,一个 example应该后跟 dividerEND .解析 blah1 后,解析器试图找到 divider失败了,然后尝试了END , 再次失败,没有其他可用选项,所以 END这是生产值(value)的最后一个选择,所以从解析器的角度来看,它期望 END , 但它很快发现,下一个输入是 blah2从第 4 行开始。

  • 如何解决?

尽量接近你的实现,你的情况下的语法应该是:

examples ::= {divider example}
divider ::= Integer")"
example ::= {literal ["END"]}

我认为将“示例”解析为 List[String]更有意义,无论如何,这取决于你。

问题是你的example解析器,它应该是一个可重复的文字。

所以,

class ParsComb extends RegexParsers {
def examples: Parser[List[Example]] = rep(divider ~ example) ^^ { _ map { case d ~ e => Example(d, e) } }
def divider: Parser[Int] = "[0-9]+".r <~ ")" ^^ (_.toInt)
def example: Parser[List[String]] = rep("[\\w]*(?=[\\r\\n])".r <~ opt("END"))
}

正则表达式 (?=[\\r\\n])意味着它是一个积极的前瞻,并且会匹配后面跟着 \r 的字符或 \n .

解析结果为:

[10.1] parsed: List(Example(0,List(blah1, blah2, blah3)), Example(1,List(blah4, blah5)))

如果你想把它解析成一个字符串(而不是 List[String] ),只需添加一个转换函数,例如: ^^ {_ mkString "\n"}

关于regex - 使用解析器组合器整理文本行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11111543/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com