13

ほとんどの場合、CSV ファイルは、レコードがカンマで区切られたテキスト ファイルです。ただし、これらのファイルはセミコロンで区切られている場合があります。(地域設定で小数点記号がコンマに設定されている場合、Excel は CSV を保存するときにセミコロン区切り記号を使用します。これはヨーロッパでは一般的です。参照: http://en.wikipedia.org/wiki/Comma-separated_values#Application_support )

私の質問は、コンマまたはセミコロンで区切られているかどうかをプログラムに推測させる最良の方法は何ですか?

たとえば、1,1;1,1 のような行はあいまいな場合があります。カンマ区切りで次のように解釈できます: 1 1;1 (文字列) 1

またはセミコロンで区切られた 1,1 1,1

これまでの私の最善の推測は、 と ; の両方でファイルを解析することです。最初の行 (通常はヘッダー行) と同じ長さの行が最も多い解析を選択します。両方の行数が同じ場合は、列数の多い方を選択します。これの主な欠点は、余分なオーバーヘッドです。

考え?

4

5 に答える 5

1

Excelの場合のように、すべての行に同じ数の列が必要な場合は、コンマとセミコロンの両方を使用して、行NとN+1の列数を計算します。どちらの方法(コンマまたはセミコロン)でも異なる答えが生成されます(ファイルの形式ではありません)。最初から始めることができ、そのうちの1つが正しくないことが証明されるまで行く必要があります。ヘッダー行などは必要ありません。必要以上にファイルを読む必要はなく、ファイルの形式について間違った答えを出すことは決してありません。ファイルが最後に到達し、まだ結論に達していない可能性があります。必要なのは、すべての行に同じ数の列プロパティを保持することだけです。

于 2010-08-03T19:54:57.520 に答える
1

何を扱っているかにもよりますが、ヘッダー行があることを保証する場合は、両方を試すというアプローチが全体的なベスト プラクティスになる可能性があります。次に、何が起こっているかを判断したら、必要な数の列がないさらに下の行に到達すると、フォーマットが正しくないことがわかります。

通常、これはプログラムによるテストではなく、アップロード時にユーザーが指定したオプションと見なされます。

于 2010-05-07T15:33:02.150 に答える
1

一行目は読める

FileReader fileReader = new FileReader(filePath);
    BufferedReader bufferedReader = new BufferedReader(fileReader);
    String s = bufferedReader.readLine();
    String substring = s.substring(s.indexOf(firstColumnName) + 3, s.indexOf(firstColumnName) + 4);
    bufferedReader.close();
    fileReader.close();
    substring.charAt(0);

次に、この値を取得します

substring.charAt(0)

CSV がカンマかセミコロンかによって、最後の値を使用できます

于 2011-12-14T23:01:19.543 に答える
0

これは私のコードです(テキストの検証はありません)...おそらくそれは助けになるか、ベースになります:-) !

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using MoreLinq; // http://stackoverflow.com/questions/15265588/how-to-find-item-with-max-value-using-linq

namespace HQ.Util.General.CSV
{
    public class CsvHelper
    {
        public static Dictionary<LineSeparator, Func<string, string[]>>  DictionaryOfLineSeparatorAndItsFunc = new Dictionary<LineSeparator, Func<string, string[]>>();

        static CsvHelper()
        {
            DictionaryOfLineSeparatorAndItsFunc[LineSeparator.Unknown] = ParseLineNotSeparated;
            DictionaryOfLineSeparatorAndItsFunc[LineSeparator.Tab] = ParseLineTabSeparated;
            DictionaryOfLineSeparatorAndItsFunc[LineSeparator.Semicolon] = ParseLineSemicolonSeparated;
            DictionaryOfLineSeparatorAndItsFunc[LineSeparator.Comma] = ParseLineCommaSeparated;
        }

        // ******************************************************************
        public enum LineSeparator
        {
            Unknown = 0,
            Tab,
            Semicolon,
            Comma
        }

        // ******************************************************************
        public static LineSeparator GuessCsvSeparator(string oneLine)
        {
            List<Tuple<LineSeparator, int>> listOfLineSeparatorAndThereFirstLineSeparatedValueCount = new List<Tuple<LineSeparator, int>>();

            listOfLineSeparatorAndThereFirstLineSeparatedValueCount.Add(new Tuple<LineSeparator, int>(LineSeparator.Tab, CsvHelper.ParseLineTabSeparated(oneLine).Count()));
            listOfLineSeparatorAndThereFirstLineSeparatedValueCount.Add(new Tuple<LineSeparator, int>(LineSeparator.Semicolon, CsvHelper.ParseLineSemicolonSeparated(oneLine).Count()));
            listOfLineSeparatorAndThereFirstLineSeparatedValueCount.Add(new Tuple<LineSeparator, int>(LineSeparator.Comma, CsvHelper.ParseLineCommaSeparated(oneLine).Count()));

            Tuple<LineSeparator, int> bestBet = listOfLineSeparatorAndThereFirstLineSeparatedValueCount.MaxBy((n)=>n.Item2);

            if (bestBet != null && bestBet.Item2 > 1)
            {
                return bestBet.Item1;
            }

            return LineSeparator.Unknown;
        }

        // ******************************************************************
        public static string[] ParseLineCommaSeparated(string line)
        {
            // CSV line parsing : From "jgr4" in http://www.kimgentes.com/worshiptech-web-tools-page/2008/10/14/regex-pattern-for-parsing-csv-files-with-embedded-commas-dou.html
            var matches = Regex.Matches(line, @"\s?((?<x>(?=[,]+))|""(?<x>([^""]|"""")+)""|""(?<x>)""|(?<x>[^,]+)),?",
                                        RegexOptions.ExplicitCapture);

            string[] values = (from Match m in matches
                               select m.Groups["x"].Value.Trim().Replace("\"\"", "\"")).ToArray();

            return values;
        }

        // ******************************************************************
        public static string[] ParseLineTabSeparated(string line)
        {
            var matchesTab = Regex.Matches(line, @"\s?((?<x>(?=[\t]+))|""(?<x>([^""]|"""")+)""|""(?<x>)""|(?<x>[^\t]+))\t?",
                            RegexOptions.ExplicitCapture);

            string[] values = (from Match m in matchesTab
                                select m.Groups["x"].Value.Trim().Replace("\"\"", "\"")).ToArray();

            return values;
        }

        // ******************************************************************
        public static string[] ParseLineSemicolonSeparated(string line)
        {
            // CSV line parsing : From "jgr4" in http://www.kimgentes.com/worshiptech-web-tools-page/2008/10/14/regex-pattern-for-parsing-csv-files-with-embedded-commas-dou.html
            var matches = Regex.Matches(line, @"\s?((?<x>(?=[;]+))|""(?<x>([^""]|"""")+)""|""(?<x>)""|(?<x>[^;]+));?",
                                        RegexOptions.ExplicitCapture);

            string[] values = (from Match m in matches
                               select m.Groups["x"].Value.Trim().Replace("\"\"", "\"")).ToArray();

            return values;
        }

        // ******************************************************************
        public static string[] ParseLineNotSeparated(string line)
        {
            string [] lineValues = new string[1];
            lineValues[0] = line;
            return lineValues;
        }

        // ******************************************************************
        public static List<string[]> ParseText(string text)
        {
            string[] lines = text.Split(new string[] { "\r\n" }, StringSplitOptions.None);
            return ParseString(lines);
        }

        // ******************************************************************
        public static List<string[]> ParseString(string[] lines)
        {
            List<string[]> result = new List<string[]>();

            LineSeparator lineSeparator = LineSeparator.Unknown;
            if (lines.Any())
            {
                lineSeparator = GuessCsvSeparator(lines[0]);
            }

            Func<string, string[]> funcParse = DictionaryOfLineSeparatorAndItsFunc[lineSeparator];

            foreach (string line in lines)
            {
                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }

                result.Add(funcParse(line));
            }

            return result;
        }

        // ******************************************************************
    }
}
于 2014-01-13T21:35:08.263 に答える
0

csv に次の内容があるとします。

title,url,date,copyright,hdurl,explanation,media_type,service_version

次に、Python の組み込み CSV モジュールを次のように使用できます。

import csv
data = "title,url,date,copyright,hdurl,explanation,media_type,service_version"
sn = csv.Sniffer()
delimiter = sn.sniff(data).delimiter

指定された変数を印刷するdelimiterと返さ','れ、これがここの区切り文字です。いくつかの異なる区切り文字を使用してテストできます。

于 2020-12-30T19:22:02.970 に答える