8

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

我的代码:

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

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

4

4 回答 4

8

由于我必须处理根据用户的本地化设置,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];
}

我还需要重置阅读器的阅读位置,因为它与我在 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

    }
}
于 2019-09-10T08:14:46.327 回答
4

我在这个网站上找到了这段代码

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 ? '\0' : separators[separatorsCount.IndexOf(maxCount)];
}

Withseparators是您可以拥有的可能的分隔符。

希望有所帮助:)

于 2015-10-26T08:35:57.847 回答
3

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

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

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

于 2015-10-26T17:27:35.887 回答
1

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

于 2021-08-08T17:58:58.410 回答