我正在嘗試學習 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))
然而,這并不漂亮,所以我仍然會應用另一個解決方案!
uj5u.com熱心網友回復:
我認為這里的主要問題是charstilldot即使失敗也會消耗字符。在這種情況下,many1chars則失敗,因為整個輸入都已被消耗。解決此問題的最簡單方法是attempt在沒有點時使用回滾:
let charstilldot = attempt (manyCharsTill anyChar (pstring "."))
let parser = opt(charstilldot) .>>. (many1Chars anyChar)
結果:
"str.ing"->(Some "str", "ing")"string"->(None, "string")
我認為還有其他很好的解決方案,但我已經嘗試為您提供一個對您當前代碼更改最少的解決方案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/335602.html
