忽略一个解析器组合任意前缀(Ignoring an arbitrary prefix in a pa

2019-10-18 08:14发布

之后厌烦了正则表达式我一直在尝试使用Scala的解析器组合库,更直观的替代正则表达式。 不过,我碰到的,当我想查找一个模式,一个字符串,而忽略的东西之前而来,例如,如果我想检查一个字符串包含单词“章鱼”我可以这样做的一个问题

val r = "octopus".r
r.findFirstIn("www.octopus.com")

这给正确Some(octopus)

然而,使用解析器组合

import scala.util.parsing.combinator._
object OctopusParser extends RegexParsers {

  def any = regex(".".r)*
  def str = any ~> "octopus" <~ any

  def parse(s: String) = parseAll(str, s) 
}

OctopusParser.parse("www.octopus.com")

不过,我得到这个错误

scala> OctopusParser.parse("www.octopus.com")
res0: OctopusParser.ParseResult[String] = 
[1.16] failure: `octopus' expected but end of source found

www.octopus.com

有没有做到这一点的好办法? 从玩耍,似乎any正在吞噬过多的投入。

Answer 1:

问题是,你的“任何”分析器是贪婪的,所以它是匹配的整条生产线,几乎没剩下什么了“STR”解析。

你可能想尝试这样的:

object OctopusParser extends RegexParsers {

  def prefix = regex("""[^\.]*\.""".r) // Match on anything other than a dot and then a dot - but only the once
  def postfix = regex("""\..*""".r)* // Grab any number of remaining ".xxx" blocks
  def str = prefix ~> "octopus" <~ postfix

  def parse(s: String) = parseAll(str, s)
}

然后给我:

scala> OctopusParser.parse("www.octopus.com")
res0: OctopusParser.ParseResult[String] = [1.13] parsed: octopus

您可能需要玩的“前缀”,以配合您所期待的输入范围,并且可能需要使用“?” 懒惰的标志如果过于贪婪。



文章来源: Ignoring an arbitrary prefix in a parser combinator