【问题标题】:FParsec match string which have one of 2 patternsFParsec 匹配具有 2 种模式之一的字符串
【发布时间】:2021-10-23 14:12:04
【问题描述】:

我正在尝试学习 FParsec 并尝试匹配两个模式中的字符串。 该字符串可以是普通字符串,如"string",也可以是一个包含一个点的字符串,如"st.ring"

解析器应如下所示:Parser<(string Option * string),unit>。第一个字符串是可选的,具体取决于字符串是否被点分隔。可选字符串表示"."之前的字符串部分。

我尝试了一些不同的方法,但我觉得这次尝试已经结束了:

let charstilldot = manyCharsTill anyChar (pstring ".")
let parser = opt(charstilldot) .>>. (many1Chars anyChar)

这适用于"st.ring" 这样的输入,但不适用于"string",因为后者中不存在点。

我会非常感谢您的帮助,谢谢!

编辑: 我有一个解决方案,它基本上按顺序解析参数并根据它们在字符串中是否是点来交换参数

let colTargetWithoutDot : Parser<string Option,unit> = spaces |>> fun _ -> None
let colTargetWithDot = (pstring "." >>. alphastring) |>> Some
let specificColumn = alphastring .>>. (colTargetWithDot <|> colTargetWithoutDot) |>> (fun (h,t) ->
    match h,t with
    | h,None -> (None,h)
    | h,Some(t) -> (Some(h),t))

但是这并不漂亮,所以我仍然会申请另一个解决方案!

【问题讨论】:

    标签: parsing f# fparsec


    【解决方案1】:

    我认为这里的主要问题是charstilldot 即使失败也会消耗字符。在那种情况下,many1chars 会失败,因为整个输入已经被消耗掉了。解决这个问题的最简单方法是在没有点时使用attempt 回滚:

    let charstilldot = attempt (manyCharsTill anyChar (pstring "."))
    let parser = opt(charstilldot) .>>. (many1Chars anyChar)
    

    结果:

    • "str.ing" -> (Some "str", "ing")
    • "string" -> (None, "string")

    我认为还有其他很好的解决方案,但我已经尝试为您提供一种对您当前代码的更改最少的解决方案。

    【讨论】:

      猜你喜欢
      • 2014-03-17
      • 2019-06-25
      • 1970-01-01
      • 2013-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-04
      • 1970-01-01
      相关资源
      最近更新 更多