我有以下子表达式来解析具有以下格式的“引号”

"5.75 @ 5.95"

因此,我有这个parsec表达式来解析它
let pquote x = (sepBy (pfloat) ((spaces .>> (pchar '/' <|>  pchar '@' )>>. spaces))) x

它很好用..除了当我的输入中有尾随空格时,当分隔符表达式开始消耗内容时,所以我将它包裹在一次尝试中,根据我的理解,这种尝试似乎有效,或多或少意味着成为。
let pquote x = (sepBy (pfloat) (attempt (spaces .>> (pchar '/' <|>  pchar '@' )>>. spaces))) x

因为我不太了解fparsec,所以我想知道是否还有更好的方法可以编写此代码。看起来有点沉重(当然仍然很容易管理)

最佳答案

let s1 = "5.75         @             5.95              "
let s2 = "5.75/5.95   "
let pquote: Parser<_> =
    pfloat
    .>> spaces .>> skipAnyOf ['@'; '/'] .>> spaces
    .>>. pfloat
    .>> spaces

笔记:
  • 我已使spaces在所有位置都是可选的spaces跳过零个或多个空格的任何序列,因此无需使用opt-谢谢@Daniel;
  • type Parser<'t> = Parser<'t, UserState>-我以此方式定义它,以避免“值限制”错误;您可以将其删除;
  • 另外,如果您的程序可以在默认语言设置为带有小数逗号的默认系统上运行,请不要忘记以下内容:System.Threading.Thread.CurrentThread.CurrentCulture <- Globalization.CultureInfo.GetCultureInfo "en-US"这将无法工作,谢谢@Stephan
  • 除非我有一个未知大小的值列表,否则我不会使用sepBy
  • 如果您确实不需要返回的值(例如'@'字符),出于性能方面的考虑,建议使用skip*函数而不是p*

  • UPD添加斜线作为分隔符

    09-09 20:08