我正在使用关于如何使用fparsec解析分隔文件的Bill Casarin帖子,我正在减少逻辑,以了解代码的工作原理。我正在将多行分隔文档解析为单元格列表结构(现在),其中Cell是字符串或浮点数。我是一个完整的新手。
我在解析浮点数时遇到问题 - 在典型情况下(由制表符分隔的单元格,包含数字)它可以正常工作。然而,当一个单元格恰好是一个以数字开头的字符串时 - 它会崩溃。
如何修改pFloatCell以解析(虽然通过选项卡的方式)作为浮点数或什么都没有?
谢谢
type Cell =
| String of string
| Float of float
.
.
.
let pStringCell delim =
manyChars (nonQuotedCellChar delim)
|>> String
// this is my issue. pfloat parses the string one
// char at a time, and once it starts off with a number
// it is down that path, and errors out
let pFloatCell delim =
FParsec.CharParsers.pfloat
|>> Float
let pCell delim =
(pFloatCell delim) <|> (pStringCell delim)
.
.
.
let ParseTab s =
let delim = "\t"
let res = run (csv delim) s in
match res with
| Success (rows, _, _) -> { IsSuccess = true; ErrorMsg = "Ok"; Result = stripEmpty rows }
| Failure (s, _, _) -> { IsSuccess = false; ErrorMsg = s; Result = [[]] }
.
.
.
let test() =
let parsed = ParseTab data
昨晚对我来说哎呀。我打算发布数据。第一个工作
let data =
"s10 Mar 2011 18:28:11 GMT\n"
虽然这会返回错误:
let data =
"10 Mar 2011 18:28:11 GMT\n"
返回,无论是否符合ChaosP的建议:
ErrorMsg =“Ln:1 Col中的错误: 3 \ r \ n10 2011年3月18:28:11 GMT \ r \ n ^ \ r \ nExpecting:文件结束,换行符 或'\ t'\ r \ n“
看起来这个尝试工作正常。在第二种情况下,它只能抓到10 - 而 pfloat的代码只能看到第一个空格。我需要提供pfloat,它需要一直向下看到下一个标签或换行符,无论它之前是否有空格;通过执行Double.Parse编写我自己的pfloat版本 - 但我宁愿依赖库。
答案 0 :(得分:2)
由于您要解析的文本似乎有点含糊不清,因此您需要修改pCell
解析器。
let sep delim =
skipString delim <|> skipAnyOf "\r\n" <|> eof
let pCell delim =
attempt (pFloatCell delim .>> sep delim) <|> (pStringCell delim .>> sep delim)
这也意味着您需要修改使用pCell
的任何解析器。
let pCells delim =
many pCell delim
注意强>
.>>
运算符实际上非常简单。把它想象成跳跃运算符。应用右侧并忽略结果后返回左侧的值。
Parser<'a, 'b> -> Parser<'c, 'b> -> Parser<'a, 'b>