Робота з комами у файлі CSV


472

Я шукаю пропозиції щодо обробки файлу csv, який створюється, а потім завантажується нашими клієнтами, і він може мати значення кома у значенні, як-от назва компанії.

Деякі ідеї, на які ми дивимось, такі: котируються ідентифікатори (значення "," значення "тощо) або використовуються | замість коми. Найбільша проблема полягає в тому, що ми повинні зробити це легко, або клієнт цього не зробить.


замовник пише це та завантажує
Bob The Janitor

1
Ось рішення для управління всередині commos у файлі CSV. відвідайте stackoverflow.com/questions/9889225/…
Хасан Абрар

на прошивкою, по суті , ви повинні використовувати github.com/Flinesoft/CSVImporter
Fattie

3
Зауважте, що цей QA старий. Сьогодні csv означає RFC 4180, і це все.
Fattie

У мене точно така ж проблема, намагаючись скласти стовпець у файлі csv, який розділений комами. Немає проблем із командою awk. На жаль, деякі комірки можуть містити коми (наприклад, у адресі), інші - не. Шукаєте сумісне рішення для Linux, але не знаєте, з чого почати.
озеленення

Відповіді:


223

Як говорили інші, вам потрібно уникнути значень, що включають лапки. Ось невеликий читач CSV в C♯, який підтримує цитовані значення, включаючи вбудовані котирування та повернення перевезення.

До речі, це тестований код. Я публікую його зараз, тому що це питання, здається, виникає багато, а інші, можливо, не хочуть цілої бібліотеки, коли буде простою підтримкою CSV.

Ви можете використовувати його наступним чином:

using System;
public class test
{
    public static void Main()
    {
        using ( CsvReader reader = new CsvReader( "data.csv" ) )
        {
            foreach( string[] values in reader.RowEnumerator )
            {
                Console.WriteLine( "Row {0} has {1} values.", reader.RowIndex, values.Length );
            }
        }
        Console.ReadLine();
    }
}

Ось класи. Зауважте, що ви можете використовувати цю Csv.Escapeфункцію і для запису дійсного CSV.

using System.IO;
using System.Text.RegularExpressions;

public sealed class CsvReader : System.IDisposable
{
    public CsvReader( string fileName ) : this( new FileStream( fileName, FileMode.Open, FileAccess.Read ) )
    {
    }

    public CsvReader( Stream stream )
    {
        __reader = new StreamReader( stream );
    }

    public System.Collections.IEnumerable RowEnumerator
    {
        get {
            if ( null == __reader )
                throw new System.ApplicationException( "I can't start reading without CSV input." );

            __rowno = 0;
            string sLine;
            string sNextLine;

            while ( null != ( sLine = __reader.ReadLine() ) )
            {
                while ( rexRunOnLine.IsMatch( sLine ) && null != ( sNextLine = __reader.ReadLine() ) )
                    sLine += "\n" + sNextLine;

                __rowno++;
                string[] values = rexCsvSplitter.Split( sLine );

                for ( int i = 0; i < values.Length; i++ )
                    values[i] = Csv.Unescape( values[i] );

                yield return values;
            }

            __reader.Close();
        }
    }

    public long RowIndex { get { return __rowno; } }

    public void Dispose()
    {
        if ( null != __reader ) __reader.Dispose();
    }

    //============================================


    private long __rowno = 0;
    private TextReader __reader;
    private static Regex rexCsvSplitter = new Regex( @",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))" );
    private static Regex rexRunOnLine = new Regex( @"^[^""]*(?:""[^""]*""[^""]*)*""[^""]*$" );
}

public static class Csv
{
    public static string Escape( string s )
    {
        if ( s.Contains( QUOTE ) )
            s = s.Replace( QUOTE, ESCAPED_QUOTE );

        if ( s.IndexOfAny( CHARACTERS_THAT_MUST_BE_QUOTED ) > -1 )
            s = QUOTE + s + QUOTE;

        return s;
    }

    public static string Unescape( string s )
    {
        if ( s.StartsWith( QUOTE ) && s.EndsWith( QUOTE ) )
        {
            s = s.Substring( 1, s.Length - 2 );

            if ( s.Contains( ESCAPED_QUOTE ) )
                s = s.Replace( ESCAPED_QUOTE, QUOTE );
        }

        return s;
    }


    private const string QUOTE = "\"";
    private const string ESCAPED_QUOTE = "\"\"";
    private static char[] CHARACTERS_THAT_MUST_BE_QUOTED = { ',', '"', '\n' };
}

2
Можливо, вам також знадобиться перекласти \ r \ n на відповідність Windows, залежно від вашої програми.
Мандраке

3
@NadaNaeem, хочете розробити?
гарпо

це неправильний підрахунок елементів у рядку файлів csv, він не дуже добре
поводиться

-1 OP не вказує мову, яка створює файл. Якщо будь-який інший програміст приходить сюди, шукаючи рішення будь-якою мовою, окрім C #, вони не знайдуть рішення, яке вони можуть використовувати у цій відповіді.
Ben Leggiero

8
@ BenC.R.Leggiero, то, гадаю, ви також повинні спростувати питання, оскільки це не відповідає вашим стандартам. У цьому коді є формальною реалізацією простої специфікації, і її можна легко перекласти на будь-яку поширену мову.
гарпо

395

На 2017 рік csv повністю вказаний - RFC 4180.

Це дуже поширена специфікація і повністю охоплена багатьма бібліотеками ( приклад ).

Просто використовуйте будь-яку легко доступну бібліотеку csv - тобто RFC 4180.


Насправді є специфікація для формату CSV та способи обробки коми:

Поля, що містять розриви рядків (CRLF), подвійні лапки та коми повинні бути укладені у подвійні лапки.

http://tools.ietf.org/html/rfc4180

Отже, щоб мати значення fooі bar,baz, ви робите це:

foo,"bar,baz"

Ще одна важлива вимога, яку слід врахувати (також від специфікації):

Якщо для закриття полів використовуються подвійні лапки, то подвійну цитату, що з’являється всередині поля, необхідно уникнути, передуючи їй ще однією подвійною цитатою. Наприклад:

"aaa","b""bb","ccc"

120
"Поля, що містять розриви рядків (CRLF), подвійні лапки та коми повинні бути укладені у подвійні лапки."
Елі

42
"Якщо подвійні лапки використовуються для укладання полів, то подвійну цитату, що з'являється всередині поля, необхідно уникнути, передуючи їй ще однією подвійною лапки."
C. Dragon 76,

11
Насправді не специфікація, але все ж, мабуть, зручна. У ній написано ... "Не існує офіційної специфікації, яка дозволяє проводити різноманітні інтерпретації файлів CSV. Цей розділ документує формат, який, як видається, дотримується більшості реалізацій."
Джастін Кларк

5
Крім того, не забувайте, що, незважаючи на свою назву, значення CSV у рядку можуть бути розділені не лише комами - принаймні на платформах Windows. Це залежить від поточних регіональних налаштувань (intl.cpl в командному рядку «Додаткові настройки»), зокрема, роздільник списку: System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator.
lxa

4
Будь ласка, покладіть відповідну інформацію у цій відповіді, на додаток до посилання, на A) Видаліть більшість вищезазначених коментарів (і моїх), B) Заощадите так багато людей, ніж відповідь, час перейти на іншу сторінку та знайти відповідну дані, C) Запобігання гниття посилань.
user66001

76

У форматі CSV використовуються коми для розділення значень, значення яких містять звороти перевезення, стрічкові стрічки, коми або подвійні лапки оточені подвійними лапками. Значення, що містять подвійні лапки, цитуються, а кожна буквальна цитата виходить безпосередньо перед цитатою: Наприклад, 3 значення:

test
list, of, items
"go" he said

буде закодовано як:

test
"list, of, items"
"""go"" he said"

Будь-яке поле може бути укладено в лапки , але тільки поля, що містять коми, CR / NL або лапки повинні бути укладені в лапки.

Немає справжнього стандарту для формату CSV, але майже всі програми дотримуються конвенцій, зафіксованих тут . RFC, який згадувався в інших місцях, не є стандартом для CSV, це RFC для використання CSV в MIME і містить деякі нетрадиційні та непотрібні обмеження, які роблять його марним поза MIME.

Отримана думка, що багато модулів CSV, які я бачив, не вміщують, - це той факт, що в одному полі може бути закодовано кілька рядків, що означає, що ви не можете вважати, що кожен рядок є окремим записом, або вам не потрібно допускати нових рядків у вашому дані або бути готовим впоратися з цим.


40

Поставте подвійні лапки навколо рядків. Це, як правило, те, що робить Excel .

Ала Елі,

ви уникаєте подвійної цитати як дві подвійні лапки. Наприклад, "test1", "foo" "bar", "test2"


в основному та сама концепція, що і котируються Ідентифікатори
Bob The Janitor

1
ви уникаєте подвійної цитати як дві подвійні лапки. Наприклад, "test1", "foo" "bar", "test2"
Eli

Просто введення подвійних лапок навколо рядка не спрацьовує, якщо «відразу слідує кома
MondKin

9

Ви можете поставити подвійні лапки навколо полів. Мені не подобається такий підхід, оскільки він додає ще одного особливого характеру (подвійна цитата). Просто визначте символ втечі (як правило, зворотний проріз) і використовуйте його там, де вам потрібно щось уникнути:

дані, більше даних, більше даних \, навіть, ще більше

Вам не потрібно намагатися співставити лапки, і у вас менше винятків для розбору. Це також спрощує ваш код.


3
Швидкий і брудний, але не працює, якщо у вас є запис, який містить "\",
Сарп Кая

1
Сарп, ось чому подвійний \\ - це втекла зворотна косої риси, оскільки тепер це стає ще одним особливим символом.
Грунгондола

1
Це працює, але це не CSV. Це DSV .
TRiG

8

Є доступна бібліотека через nuget для роботи з майже будь-яким добре сформованим CSV (.net) - CsvHelper

Приклад для зіставлення класу:

var csv = new CsvReader( textReader );
var records = csv.GetRecords<MyClass>();

Приклад для читання окремих полів:

var csv = new CsvReader( textReader );
while( csv.Read() )
{
    var intField = csv.GetField<int>( 0 );
    var stringField = csv.GetField<string>( 1 );
    var boolField = csv.GetField<bool>( "HeaderName" );
}

Дозволити клієнту керувати файловим форматом:
, це стандартний роздільник поля, "це стандартне значення, яке використовується для виходу з полів, що містять роздільник, лапку або закінчення рядка.

Щоб використовувати (наприклад) #для полів і 'для втечі:

var csv = new CsvReader( textReader );
csv.Configuration.Delimiter = "#";
csv.Configuration.Quote = ''';
// read the file however meets your needs

Більше документації


3
Було б краще, якщо ви включили приклад того, як використовувати CsvHelperбібліотеку для вирішення проблеми ОП.
Джордж Стокер

Чому майже все в. Net має стати "помічником" ... слово майже безглуздо ... як "Менеджер".
bytedev

5

Як було сказано в моєму коментарі до відповіді гарпо, його рішення є хорошим і працює в більшості випадків, однак у деяких сценаріях, коли коми як безпосередньо примикають один до одного, вони не розбиваються на коми.

Це відбувається через те, що рядок Regex несподівано поводиться як вертабітна рядок. Для того, щоб це поводилося правильно, всі "символи в рядку регулярних виразів повинні бути виведені вручну без використання вертабімного втечі.

Тобто Регекс повинен бути таким, використовуючи ручні втечі:

",(?=(?:[^\"\"]*\"\"[^\"\"]*\"\")*(?![^\"\"]*\"\"))"

що перекладається на ",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))"

При використанні рядка vertabim @",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))"він поводиться так, як ви бачите, якщо ви налагоджуєте регулярний вираз:

",(?=(?:[^"]*"[^"]*")*(?![^"]*"))"

Отже, підводячи підсумок, я рекомендую рішення гарпу, але стежте за цим маленьким гатчем!

Я включив у CsvReader невеликий необов’язковий помилку, щоб повідомити вас про помилку (якщо у вас є попередньо відома кількість стовпців):

if (_expectedDataLength > 0 && values.Length != _expectedDataLength) 
throw new DataLengthException(string.Format("Expected {0} columns when splitting csv, got {1}", _expectedDataLength, values.Length));

Це можна вводити через конструктор:

public CsvReader(string fileName, int expectedDataLength = 0) : this(new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
    _expectedDataLength = expectedDataLength;
}

Як би ви вирішили обробляти рядок заголовка? Я намагаюся зіставити csv на об'єкти C #, які є всіма типами, але заголовок рядок порушує його, тому що всі його рядки ...
tCoe

Це не [^""]те саме, що [^"]? Дублювання символу всередині специфікації класу символів є зайвим, правда?
Мінь Тран

4

Додайте посилання на Microsoft.VisualBasic (так, він говорить про VisualBasic, але він працює на C # так само добре - пам’ятайте, що в кінці все це просто IL).

Використовуйте Microsoft.VisualBasic.FileIO.TextFieldParserклас для розбору CSV-файлів Ось зразок коду:

 Dim parser As TextFieldParser = New TextFieldParser("C:\mar0112.csv")
 parser.TextFieldType = FieldType.Delimited
 parser.SetDelimiters(",")      

   While Not parser.EndOfData         
      'Processing row             
      Dim fields() As String = parser.ReadFields         
      For Each field As String In fields             
         'TODO: Process field                   

      Next      
      parser.Close()
   End While 

Так, це дуже корисний клас у дещо невдалому просторі імен ;-). Однак для вирішення оригінального питання слід також встановити, parser.HasFieldsEnclosedInQuotes = true;і вхідний файл повинен містити поля, які містять коми в лапках відповідно до специфікації CSV - excel це вже робить.
Крістофер Кінг,

4

Ви можете використовувати альтернативні "роздільники" типу ";" або "|" але найпростішим може бути лише цитування, яке підтримується більшістю (пристойних) бібліотек CSV та найпристойнішими електронними таблицями.

Для більш на CSV роздільниках і в специфікації для стандартного формату для опису роздільників і цитування бачити цей веб - сторінку


4

У разі , якщо ви на * NIX-системі , має доступ до sedі може бути один або кілька небажаних коми тільки в конкретній галузі вашого CSV, ви можете використовувати наступний однострочнікі для того , щоб вкласти їх в "якості RFC4180 розділу 2 пропозиції:

sed -r 's/([^,]*,[^,]*,[^,]*,)(.*)(,.*,.*)/\1"\2"\3/' inputfile

Залежно від того, яке поле може знаходитись небажана кома (и), вам доведеться змінити / розширити групи захоплення регулярного виразів (і підстановки).
Наведений вище приклад додасть четверте поле (з шести) у лапки.

введіть тут опис зображення

У поєднанні з --in-placeопцією ви можете застосувати ці зміни безпосередньо до файлу.

Щоб "побудувати" правильний вираз, слід простий принцип:

  1. Для кожного поля у вашому CSV, який виходить перед полем із небажаними комами (цими), ви пишете [^,]*,їх і складаєте їх усіх у групу захоплення.
  2. Для поля, яке містить небажані коми, які ви пишете (.*).
  3. Для кожного поля після поля із небажаною комою (іми) ви пишете один ,.* і складаєте їх разом у групу захоплення.

Ось короткий огляд різних можливих регексів / замін залежно від конкретного поля. Якщо його не дано, заміна є \1"\2"\3.

([^,]*)(,.*)                     #first field, regex
"\1"\2                           #first field, substitution

(.*,)([^,]*)                     #last field, regex
\1"\2"                           #last field, substitution


([^,]*,)(.*)(,.*,.*,.*)          #second field (out of five fields)
([^,]*,[^,]*,)(.*)(,.*)          #third field (out of four fields)
([^,]*,[^,]*,[^,]*,)(.*)(,.*,.*) #fourth field (out of six fields)

Якщо ви хочете видалити небажані коми (-и), sedа не додавати їх у лапки, зверніться до цієї відповіді .


3

Якщо ви хочете винаходити колесо, вам може допомогти наступне:

public static IEnumerable<string> SplitCSV(string line)
{
    var s = new StringBuilder();
    bool escaped = false, inQuotes = false;
    foreach (char c in line)
    {
        if (c == ',' && !inQuotes)
        {
            yield return s.ToString();
            s.Clear();
        }
        else if (c == '\\' && !escaped)
        {
            escaped = true;
        }
        else if (c == '"' && !escaped)
        {
            inQuotes = !inQuotes;
        }
        else
        {
            escaped = false;
            s.Append(c);
        }
    }
    yield return s.ToString();
}

3

В Європі у нас ця проблема повинна бути раніше, ніж це питання. У Європі ми використовуємо всю кому для десяткової крапки. Дивіться ці цифри нижче:

| American      | Europe        |
| ------------- | ------------- |
| 0.5           | 0,5           |
| 3.14159265359 | 3,14159265359 |
| 17.54         | 17,54         |
| 175,186.15    | 175.186,15    |

Тому використовувати роздільник комах для файлів CSV неможливо. З цієї причини файли CSV в Європі розділені крапкою з комою ( ;) .

Такі програми, як Microsoft Excel, можуть читати файли з крапкою з комою та можливо перейти з роздільника. Ви навіть можете використовувати вкладку ( \t) як роздільник. Дивіться цю відповідь від Supper User .


2

Якщо вас цікавить більш навчальна вправа про те, як аналізувати файли взагалі (використовуючи CSV як приклад), ви можете ознайомитись із цією статтею Джуліана Бакналла. Стаття мені подобається, оскільки вона розбиває речі на набагато менші проблеми, які є набагато менш непереборними. Спочатку ви створюєте граматику, і коли ви маєте гарну граматику, це відносно легкий і методичний процес перетворення граматики в код.

У статті використовується C # та є посилання внизу для завантаження коду.


1

Ось акуратний маленький спосіб вирішення:

Ви можете замість цього використовувати грецький нижній числовий знак (U + 0375)

Так виглядає this

Використання цього методу заощаджує також багато ресурсів ...


1

Просто використовуйте SoftCircuits.CsvParser на NuGet. Він обробляє всі ці деталі для вас і ефективно обробляє дуже великі файли. І, якщо потрібно, він може навіть імпортувати / експортувати об'єкти, зіставляючи стовпці для властивостей об'єкта. Крім того, моє тестування показало, що в середньому це майже в 4 рази швидше, ніж популярний CsvHelper.


0

Оскільки мова йде про загальні практики, почнемо з правил:

  1. Не використовуйте CSV, використовуйте XML з бібліотекою для читання та запису файлу xml.

  2. Якщо потрібно використовувати CSV Зробіть це правильно та використовуйте безкоштовну бібліотеку для розбору та зберігання файлів CSV.

Для виправдання 1) більшість CSV-аналізаторів не кодують, тому якщо ви не маєте стосунків з US-ASCII, ви просите про проблеми. Наприклад, excel 2002 зберігає CSV у локальному кодуванні без будь-яких приміток про кодування. Стандарт CSV не є широко прийнятим :(. З іншого боку, стандарт xml добре прийнятий і він обробляє кодування досить добре.

Для того, щоб виправдати 2), існує безліч csv-аналізаторів майже на всій мові, тому немає необхідності винаходити колесо, навіть якщо рішення виглядає досить просто.

Щоб назвати декілька:

  • для використання python, побудованого в модулі csv

  • для перевірки Perl CPAN та Text :: CSV

  • для використання php вбудувати функції fgetcsv / fputcsv

  • для Java перевірити бібліотеку SuperCVS

Дійсно, немає необхідності реалізовувати це вручну, якщо ви не збираєтесь його розбирати на вбудованому пристрої.


12
XML не завжди є відповіддю. CSV - це правильний формат для роботи, коли у вас є багато щільних табличних даних (тобто електронної таблиці). Ці теги містять багато накладних витрат, і якщо кожен рядок має однаковий формат, не потрібно чітко пояснювати, що представляє кожне значення. XML чудово підходить, коли у вас складні ієрархічні дані або записи з необов’язковими полями. Це не завжди так.
Адам Яскевич

Теоретично "теги" вносять трохи накладних витрат, але я не можу придумати жодного додатку в реальному житті, де це може стати проблемою. Чи є у вас якісь практичні приклади? Для роботи над даними слід використовувати базу даних замість csv. якщо ми говоримо про серіалізацію даних (резервне копіювання, обмін даними), чи буде мати значення, якщо аналіз займає тиждень замість 5 днів?
Пьотр Чапла

2
В основному, будь-яка ситуація, в якій у вас є дані, найкраще представлена ​​таблицею. Скажімо, у вас є дані з десятка різних датчиків, які ви берете на вибірку так часто, і ви записуєте часові позначки та значення кожного з датчиків на той час. Кожен запис ідентичний: часова марка, датчик0, датчик1, ... датчик11. XML чудово підходить для представлення складних, нерегулярних даних, але це досить важкий формат, який не відповідає кожній ситуації. KISS
Адам Яскевич

10
Деякі люди бачать проблему, і вони кажуть "Я знаю, я буду використовувати XML!" Зараз у них дві проблеми.
Адам Яскевич

Я повністю згоден, що xml - це не відповідь на все. Особливо він не підходить як заміна бази даних, ні для файлів конфігурації. Але тут питання стосувалося обміну даними, для яких було розроблено XML.
Пьотр Чапла

0

Ви можете прочитати файл CSV, як це.

це використовує розколи та піклується про місця.

ArrayList List = new ArrayList();
static ServerSocket Server;
static Socket socket;
static ArrayList<Object> list = new ArrayList<Object>();


public static void ReadFromXcel() throws FileNotFoundException
{   
    File f = new File("Book.csv");
    Scanner in = new Scanner(f);
    int count  =0;
    String[] date;
    String[] name;
    String[] Temp = new String[10];
    String[] Temp2 = new String[10];
    String[] numbers;
    ArrayList<String[]> List = new ArrayList<String[]>();
    HashMap m = new HashMap();

         in.nextLine();
         date = in.nextLine().split(",");
         name = in.nextLine().split(",");
         numbers = in.nextLine().split(",");
         while(in.hasNext())
         {
             String[] one = in.nextLine().split(",");
             List.add(one);
         }
         int xount = 0;
         //Making sure the lines don't start with a blank
         for(int y = 0; y<= date.length-1; y++)
         {
             if(!date[y].equals(""))
             {   
                 Temp[xount] = date[y];
                 Temp2[xount] = name[y];
                 xount++;
             }
         }

         date = Temp;
         name =Temp2;
         int counter = 0;
         while(counter < List.size())
         {
             String[] list = List.get(counter);
             String sNo = list[0];
             String Surname = list[1];
             String Name = list[2];
             for(int x = 3; x < list.length; x++)
             {           
                 m.put(numbers[x], list[x]);
             }
            Object newOne = new newOne(sNo, Name, Surname, m, false);
             StudentList.add(s);
             System.out.println(s.sNo);
             counter++;
         }

0

Спочатку давайте запитаємо себе: "Чому ми відчуваємо необхідність по-різному обробляти коми для файлів CSV?"

Для мене відповідь така: "Тому що коли я експортую дані у файл CSV, коми в полі зникають, і моє поле відокремлюється на кілька полів, де коми містяться в початкових даних". (Це тому, що кома є символом роздільника CSV поля.)

Залежно від вашої ситуації напівколонки можуть також використовуватися як роздільники полів CSV.

З огляду на мої вимоги, я можу використовувати символ, наприклад, одинарний лапки з низьким рівнем 9, який виглядає як кома.

Отже, ось як це можна зробити в Go:

// Replace special CSV characters with single low-9 quotation mark
func Scrub(a interface{}) string {
    s := fmt.Sprint(a)
    s = strings.Replace(s, ",", "‚", -1)
    s = strings.Replace(s, ";", "‚", -1)
    return s
}

Другий символ, який шукає кома у функції «Замінити», - десятковий 8218.

Майте на увазі, що якщо у вас є клієнти, у яких можуть бути лише користувачі, що читають текст ascii, цей символ decima 8218 не буде схожий на коми. Якщо це ваш випадок, то я рекомендую оточити поле комою (або крапкою з комою) з подвійними лапки на RFC 4128: https://tools.ietf.org/html/rfc4180


0

Я зазвичай кодую URL-адреси поля, які можуть мати будь-які коми або будь-які спеціальні символи. А потім розшифруйте його під час використання / відображення на будь-якому візуальному носії.

(коми стають% 2C)

Кожна мова повинна мати методи кодування URL-адрес та декодування рядків.

наприклад, у java

URLEncoder.encode(myString,"UTF-8"); //to encode
URLDecoder.decode(myEncodedstring, "UTF-8"); //to decode

Я знаю, що це дуже загальне рішення, і воно може бути не ідеальним для ситуації, коли користувач хоче переглянути вміст CSV-файлу вручну.


0

Зазвичай я це роблю у своїх CSV-файлах, розбираючи підпрограми. Припустимо, що змінна "рядок" - це один рядок у файлі CSV, і всі значення стовпців укладаються у подвійні лапки. Після виконання наведених нижче двох рядків, ви отримаєте стовпці CSV у колекції "значень".

// The below two lines will split the columns as well as trim the DBOULE QUOTES around values but NOT within them
    string trimmedLine = line.Trim(new char[] { '\"' });
    List<string> values = trimmedLine.Split(new string[] { "\",\"" }, StringSplitOptions.None).ToList();

1
Чому мій код ніколи не відображається у кількох кольорах на StackOverflow? Я відступаю чотирма пробілами.
користувач1451111


0

Найпростіше рішення, яке я знайшов, - це те, яке використовує LibreOffice:

  1. Замініть все буквальне "на
  2. Покладіть подвійні лапки навколо рядка

Ви також можете використовувати той, який використовує Excel:

  1. Замініть все буквальне "на""
  2. Покладіть подвійні лапки навколо рядка

Зауважте, що інші люди рекомендують зробити лише крок 2 вище, але це не працює з рядками, де a " , за якими a ,, а після , як у CSV, де ви хочете мати один стовпець із рядком hello",world, як CSV читатиме:

"hello",world"

Який інтерпретується як рядок з двома стовпцями: helloіworld"


1
За стандартними правилами, будь-яке поле, що містить або розділений символ, або цитату, оточене цитатами, а будь-які цитати всередині яких подвоюються, тому немає жодної проблеми. Ваше hello",worldполе просто потрібно було б зберегти як "hello"",world", що можна правильно розібрати на 100%.
Nyerguds

0
    public static IEnumerable<string> LineSplitter(this string line, char 
         separator, char skip = '"')
    {
        var fieldStart = 0;
        for (var i = 0; i < line.Length; i++)
        {
            if (line[i] == separator)
            {
                yield return line.Substring(fieldStart, i - fieldStart);
                fieldStart = i + 1;
            }
            else if (i == line.Length - 1)
            {
                yield return line.Substring(fieldStart, i - fieldStart + 1);
                fieldStart = i + 1;
            }

            if (line[i] == '"')
                for (i++; i < line.Length && line[i] != skip; i++) { }
        }

        if (line[line.Length - 1] == separator)
        {
            yield return string.Empty;
        }
    }

0

Я використовував бібліотеку Csvreader, але за допомогою цього я отримав дані, вибухнувши з коми (,) у значення стовпця.

Отже, якщо ви хочете вставити дані файлу CSV, які містять коми (,) у більшості значень стовпців, ви можете використовувати функцію нижче. Авторське посилання => https://gist.github.com/jaywilliams/385876

function csv_to_array($filename='', $delimiter=',')
{
    if(!file_exists($filename) || !is_readable($filename))
        return FALSE;

    $header = NULL;
    $data = array();
    if (($handle = fopen($filename, 'r')) !== FALSE)
    {
        while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE)
        {
            if(!$header)
                $header = $row;
            else
                $data[] = array_combine($header, $row);
        }
        fclose($handle);
    }
    return $data;
}

0

Я використовував бібліотеку papaParse, щоб проаналізувати файл CSV та мати пари ключ-значення (ключ / заголовок / перший рядок файлу-значення CSV).

ось приклад, який я використовую:

https://codesandbox.io/embed/llqmrp96pm

він має dummy.csv файл там, щоб мати демонстрацію CSV для аналізу.

Я використовував його в reactJS, хоча легко і просто копіювати в додатку, написаному будь-якою мовою.


0

Приклад може допомогти показати, як коми можуть відображатися у файлі .csv. Створіть простий текстовий файл наступним чином:

Збережіть цей текстовий файл як текстовий файл із суфіксом ".csv" та відкрийте його за допомогою Excel 2000 з Windows 10.

aa, bb, cc, d; d "У презентації електронних таблиць рядок нижче повинен бути схожим на вищевказаний рядок, за винятком того, що внизу показана відображена кома замість крапки з комою між d". aa, bb, cc, "d, d", Це працює навіть в Excel

aa, bb, cc, "d, d", це працює навіть у Excel 2000 aa, bb, cc, "d, d", це працює навіть у Excel 2000 aa, bb, cc, "d, d", це працює навіть у Excel 2000

aa, bb, cc, "d, d", ця помилка в Excel 2000 через космос кохання 1-а цитата aa, bb, cc, "d, d", ця помилка в програмі Excel 2000 через космос кохання 1-й цитатою aa, bb, cc, "d, d", це виходить з ладу в Excel 2000 через космос кохання 1-й цитатою

aa, bb, cc, "d, d", Це працює навіть в Excel 2000 навіть з пробілами до та після другої цитати. aa, bb, cc, "d, d", Це працює навіть в Excel 2000 навіть з пробілами до та після другої цитати. aa, bb, cc, "d, d", Це працює навіть в Excel 2000 навіть з пробілами до та після другої цитати.

Правило: Якщо ви хочете відобразити кому в комірці (полі) файлу .csv: "Почніть і закінчіть поле подвійними лапками, але уникайте пробілів перед першою цитатою"


-1

Я думаю, що найпростіше вирішити цю проблему - замовити клієнт відкрити csv в excel, а потім ctrl + r замінити всі коми на будь-який ідентифікатор, який ви хочете. Це дуже просто для замовника і вимагає лише однієї зміни коду, щоб прочитати роздільник, який ви обрали.


Хто каже, що вони мають Excel? Насправді хто каже, що це навіть людина, яка робить завантаження? ...
bytedev

-3

Використовуйте символ вкладки (\ t), щоб розділити поля.


4
-1 Чудово, поки хтось не використає вкладку в їх цінність, тоді ви повернетесь до проблеми, яку має людина, яка задає питання. Помінявши один знак розмежувача на інший, не вирішувати проблему.
bytedev

Дурниці. Люди не можуть вводити вкладки під час введення даних. У більшості форм це просто переміщує точку введення даних у наступне поле.
П’єр

6
"Люди не можуть вводити вкладки під час введення даних" .... Ви серйозно ?? А) звичайно, людина може поставити вкладку в поле введення В) хто каже, що це графічний інтерфейс, з якого беруться дані? В) хто каже, що це навіть людина, яка вводить дані?
bytedev
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.