CsvHelper:如何从给定的 csv 文件中检测定界符

CsvHelper : How to detect the Delimiter from the given csv file

我正在使用 CsvHelper read/writer 将数据导入 Csv 文件。现在我想解析 csv 文件的分隔符。请问我怎样才能得到这个?

我的代码:

     var parser = new CsvParser(txtReader);
     delimiter = parser.Configuration.Delimiter;

我总是得到分隔符是“,”,但实际上在 csv 文件中分隔符是“\t”。

我在这个site

中找到了这段代码
public static char Detect(TextReader reader, int rowCount, IList<char> separators)
{
    IList<int> separatorsCount = new int[separators.Count];

    int character;

    int row = 0;

    bool quoted = false;
    bool firstChar = true;

    while (row < rowCount)
    {
        character = reader.Read();

        switch (character)
        {
            case '"':
                if (quoted)
                {
                    if (reader.Peek() != '"') // Value is quoted and 
            // current character is " and next character is not ".
                        quoted = false;
                    else
                        reader.Read(); // Value is quoted and current and 
                // next characters are "" - read (skip) peeked qoute.
                }
                else
                {
                    if (firstChar)  // Set value as quoted only if this quote is the 
                // first char in the value.
                        quoted = true;
                }
                break;
            case '\n':
                if (!quoted)
                {
                    ++row;
                    firstChar = true;
                    continue;
                }
                break;
            case -1:
                row = rowCount;
                break;
            default:
                if (!quoted)
                {
                    int index = separators.IndexOf((char)character);
                    if (index != -1)
                    {
                        ++separatorsCount[index];
                        firstChar = true;
                        continue;
                    }
                }
                break;
        }

        if (firstChar)
            firstChar = false;
    }

    int maxCount = separatorsCount.Max();

    return maxCount == 0 ? '[=10=]' : separators[separatorsCount.IndexOf(maxCount)];
}

separators 是您可以使用的分隔符。

希望有所帮助:)

CSV 是 Comma 分隔值。我认为您无法可靠地检测到是否使用了不同的字符作为分隔符。如果有 header 行,那么您也许可以指望它。

您应该知道使用的分隔符。打开文件时您应该能够看到它。如果文件来源每次都给你一个不同的分隔符并且不可靠,那么我很抱歉。 ;)

如果您只想使用不同的分隔符进行解析,那么您可以设置csv.Configuration.Delimiterhttp://joshclose.github.io/CsvHelper/#configuration-delimiter

由于我不得不处理 CSV 文件(保存在 MS Excel 中)可能包含不同分隔符的可能性,具体取决于用户的本地化设置,我最终采用了以下方法:

public static string DetectDelimiter(StreamReader reader)
{
    // assume one of following delimiters
    var possibleDelimiters =  new List<string> {",",";","\t","|"};

    var headerLine = reader.ReadLine();

    // reset the reader to initial position for outside reuse
    // Eg. Csv helper won't find header line, because it has been read in the Reader
    reader.BaseStream.Position = 0;
    reader.DiscardBufferedData();

    foreach (var possibleDelimiter in possibleDelimiters)
    {
        if (headerLine.Contains(possibleDelimiter))
        {
            return possibleDelimiter;
        }
    }

    return possibleDelimiters[0];
}

我还需要重置 reader 的读取位置,因为它与我在 CsvReader 构造函数中使用的实例相同。

当时的用法如下:

using (var textReader = new StreamReader(memoryStream))
{
    var delimiter = DetectDelimiter(textReader);

    using (var csv = new CsvReader(textReader))
    {
        csv.Configuration.Delimiter = delimiter;

        ... rest of the csv reader process

    }
}

有(至少现在)一个设置为 false 的 DetectDelimiter 值。 然后你可以添加你想测试的愿望分隔符,尽管默认是合理的