4

我正在使用出色的 FileHelpers 库来解析许多不同的文件。其中一个文件有(一些)行看起来像这样

id|name|comments|date
01|edov|bla bla bla bla|2012-01-01
02|john|bla bla bla bla|2012-01-02
03|Pete|bla bla <NEWLINE>
bla bla|2012-03-01
04|Mary|bla bla bla bla|2012-01-01

请注意,id 为 3 的行在文本中有一个换行符。另请注意,评论没有被引号包围,所以[FieldQuoted('"', MultilineMode.AllowForRead)]不会救我。

Filehelpers 在第 4 行抛出异常:

分隔符“|” 在字段“评论”之后找不到(记录的字段较少,分隔符错误或下一个字段必须标记为可选)。

无论如何我可以用 FileHelpers 解析这个文件吗?

4

1 回答 1

3

在将输入传递给 FileHelpers 引擎之前,您必须通过在第三个字段中添加引号来更正输入。使用 LINQ 很容易,如以下程序所示。

[DelimitedRecord("|")]
[IgnoreFirst(1)]
public class ImportRecord
{
    public string Id;
    public string Name;
    [FieldQuoted(QuoteMode.AlwaysQuoted, MultilineMode.AllowForRead)]
    public string Comments;
    public string Date;
}

class Program
{
    static void Main(string[] args)
    {
        var engine = new FileHelperEngine<ImportRecord>();

        string input = "id|name|comments|date" + Environment.NewLine +
                              "01|edov|bla bla bla bla|2012-01-01" + Environment.NewLine +
                              "02|john|bla bla bla bla|2012-01-02" + Environment.NewLine +
                              "03|Pete|bla bla" + Environment.NewLine +
                              "bla bla|2012-03-01" + Environment.NewLine +
                              "04|Mary|bla bla bla bla|2012-01-01";

        // Modify import to add quotes to multiline fields
        var inputSplitAtSeparator = input.Split('|');
        // Add quotes around the field after every third '|'
        var inputWithQuotesAroundCommentsField = inputSplitAtSeparator.Select((x, i) => (i % 3 == 2) ? "\"" + x + "\"" : x);
        var inputJoinedBackTogether = String.Join("|", inputWithQuotesAroundCommentsField);

        ImportRecord[] validRecords = engine.ReadString(inputJoinedBackTogether);

        // Check the third record
        Assert.AreEqual("03", validRecords[2].Id);
        Assert.AreEqual("Pete", validRecords[2].Name);
        Assert.AreEqual("bla bla" + Environment.NewLine + "bla bla", validRecords[2].Comments);
        Assert.AreEqual("2012-03-01", validRecords[2].Date);

        Console.WriteLine("All assertions passed");
        Console.ReadKey();
    }
}
于 2012-07-20T11:26:20.257 回答