首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将给定的“n”字符与FastParse准确匹配

如何将给定的“n”字符与FastParse准确匹配
EN

Stack Overflow用户
提问于 2015-06-13 12:27:26
回答 3查看 540关注 0票数 3

FastParse解析器-combinator库为您提供了.rep(n)“重复”方法,允许您创建一个尝试解析givenParser n或更多次的新解析器。如果我想要精确的n匹配,那么常规的方法是什么呢?

在我的例子中,我想解析一个40个字符的Git提交id --如果它超过40个字符,那就不是提交id,它不应该是匹配的。

到目前为止,我在docs中发现的最接近的例子是:

代码语言:javascript
复制
val unicodeEscape = P( "u" ~ hexDigit ~ hexDigit ~ hexDigit ~ hexDigit )

...which用简单的重复匹配4个字符(40个字符提交id的详细内容)。

这些是解析器-组合子,而不是正则表达式,答案应该是类似于\p{XDigit}{40}的东西。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-01-01 19:55:14

由于问题被这个提交关闭,rep支持一个max关键字参数。它现在还支持一个精确的关键字参数。

代码语言:javascript
复制
hexdigit.rep(exactly = 40)
票数 7
EN

Stack Overflow用户

发布于 2015-06-13 13:27:21

好吧,即使这个功能现在不可用,您也可以编写一个函数,将~应用到给定的次数:

代码语言:javascript
复制
def repExactly(parser: Parser[Unit])(times: Int): Parser[Unit] =
  Iterator.iterate(parser)(_ ~ parser).drop(times - 1).next()

下面是一个小小的测试:

代码语言:javascript
复制
object Main extends App {

  import fastparse._

  def repExactly(parser: Parser[Unit])(times: Int): Parser[Unit] =
    Iterator.iterate(parser)(_ ~ parser).drop(times - 1).next()

  val hexDigit = P( CharIn('0'to'9', 'a'to'f', 'A'to'F') )
  def fiveHexDigits = repExactly(hexDigit)(5) ~ End

  println(fiveHexDigits.parse("123a"))
  println(fiveHexDigits.parse("123ab"))
  println(fiveHexDigits.parse("123abc"))

}

输出是

代码语言:javascript
复制
Failure(hexDigit:4 / CharIn("0123456789abcdefABCDEF"):4 ..."", false)
Success((), 5)
Failure(End:5 ..."c", false)

这里有一种作为运算符* of Parser来实现此功能的通用方法( rep做了一些非常复杂的事情,所以我的实现可能不考虑某些情况。此外,我也没有测试它是如何与具有裁剪的参数一起工作的):

代码语言:javascript
复制
object Main extends App {

  import fastparse._

  implicit class ParserExtension[T](parser: Parser[T]) {
    def *[R] (times: Int)(implicit ev: Implicits.Repeater[T, R]): Parser[R] = {
      assert(times >= 1)

      Iterator.iterate(parser map { t =>
        val acc = ev.initial
        ev.accumulate(t, acc)
        acc
      }){ prev: Parser[ev.Acc] =>
        (prev ~ parser) map {
          case (acc, t) =>
            ev.accumulate(t, acc)
            acc
        }
      }.drop(times - 1).next() map (acc => ev.result(acc))
    }
  }

  val hexDigit = P( CharIn('0'to'9', 'a'to'f', 'A'to'F') )

  val fiveDigitsSeq = (hexDigit.! * 5) ~ End

  println(fiveDigitsSeq.parse("123a"))   // Failure ...
  println(fiveDigitsSeq.parse("123ab"))  // Success(ArrayBuffer(1, 2, 3, a, b), 5)
  println(fiveDigitsSeq.parse("123abc")) // Failure ...
  println()

  val fiveDigitsStr = (hexDigit * 5).! ~ End

  println(fiveDigitsStr.parse("123a"))   // Failure ...
  println(fiveDigitsStr.parse("123ab"))  // Success(123ab, 5)
  println(fiveDigitsStr.parse("123abc")) // Failure ...
}
票数 4
EN

Stack Overflow用户

发布于 2015-06-13 13:19:12

啊,看起来它现在还不可用,但是对于FastParse来说,它是一个已知的“缺失特性”:

https://github.com/lihaoyi/fastparse/issues/27

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30818673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档