CSV 파일에서 쉼표 처리


472

고객이 생성하고 업로드 한 회사 이름과 같은 쉼표가있는 CSV 파일을 처리하는 방법에 대한 제안을 찾고 있습니다.

우리가보고있는 아이디어 중 일부는 다음과 같습니다. 따옴표 붙은 식별자 (값 ","값 "등") 또는 | 쉼표 대신. 가장 큰 문제는 우리가 쉽게 만들지 않으면 고객이 그렇게하지 않아야한다는 것입니다.


고객이 작성하여 업로드 중
Bob The Janitor

1
CSV 파일의 쉼표 내부를 관리하는 솔루션은 다음과 같습니다. stackoverflow.com/questions/9889225/…
Hasan Abrar

iOS에서는 기본적으로 github.com/Flinesoft/CSVImporter
Fattie

3
이 품질 보증은 오래되었습니다. 요즘 csv는 RFC 4180을 의미 합니다.
Fattie

쉼표로 구분 된 CSV 파일의 열을 합계하려고하는 것과 정확히 동일한 문제가 있습니다. awk 명령에는 문제가 없습니다. 불행하게도 일부 셀은 쉼표를 포함 할 수 있으며 (예 : 주소) 다른 셀은 그렇지 않습니다. Linux 호환 솔루션을 찾고 있지만 시작 위치를 확실하지 않습니다.
greenage

답변:


223

다른 사람들이 말했듯이 따옴표가 포함 된 값을 이스케이프해야합니다. C♯에 포함 된 작은 따옴표 및 캐리지 리턴을 포함하여 따옴표로 묶은 값을 지원하는 작은 CSV 리더기가 있습니다.

그건 그렇고, 이것은 단위 테스트 코드입니다. 이 질문이 많이 나오고 간단한 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
응용 프로그램에 따라 Windows 호환을 위해 \ r \ n을 번역해야 할 수도 있습니다.
Mandrake

3
@NadaNaeem, 정교하게 관리?
harpo

CSV 파일 행의 항목을 올바르게 계산하지 않고 필드의 쉼표와 용기 반환 및 탭을 잘 처리하지 못합니다
.

-1 OP는 파일을 생성하는 언어를 지정하지 않습니다. C # 이외의 언어로 솔루션을 찾는 다른 프로그래머가 여기에 오면이 답변에 사용할 수있는 솔루션을 찾지 못할 것입니다.
Ben Leggiero

8
@ BenC.R. Leggiero, 당신은 표준에 의해 대답 할 수 없기 때문에 질문을 downvote해야한다고 생각합니다. 이 코드는 간단한 사양을 공식적으로 구현 한 것으로 일반적으로 사용되는 언어로 쉽게 번역 할 수 있습니다.
harpo

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), 큰 따옴표 및 쉼표가 포함 된 필드는 큰 따옴표로 묶어야합니다."
Eli

42
"큰 따옴표를 사용하여 필드를 묶는 경우 다른 큰 따옴표를 앞에 두어 필드 안에 나타나는 큰 따옴표를 이스케이프해야합니다."
C. Dragon 76

11
실제로 사양은 아니지만 여전히 편리합니다. "공식 사양이 존재하지 않아 CSV 파일을 다양하게 해석 할 수 있습니다.이 섹션에는 대부분의 구현이 따르는 형식이 문서화되어 있습니다."
Justin Clarke

5
또한 이름에도 불구하고 행의 CSV 값은 최소한 Windows 플랫폼에서 쉼표로 구분 될 수 있습니다. 현재 지역 설정 (명령 줄의 intl.cpl, "고급 설정"), 특히 목록 구분 기호에 따라 다릅니다 System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator.
lxa

4
링크와 함께이 답변에 관련 정보를 입력하십시오. A) 위의 의견을 대부분 제거하십시오. 데이터, C) 링크 썩음 방지.
user66001

76

CSV 형식은 쉼표를 사용하여 값을 구분합니다. 캐리지 리턴, 줄 바꿈, 쉼표 또는 큰 따옴표가 포함 된 값은 큰 따옴표로 묶습니다. 큰 따옴표가 포함 된 값은 따옴표로 묶고 각 리터럴 따옴표는 바로 앞의 따옴표로 이스케이프됩니다.

test
list, of, items
"go" he said

다음과 같이 인코딩됩니다.

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

모든 필드는 인용 할 수 있지만 쉼표, CR / NL 또는 인용 부호가 포함 된 필드 만 인용 해야 합니다.

CSV 형식에 대한 실제 표준 은 없지만 거의 모든 응용 프로그램이 여기에 설명 된 규칙을 따릅니다 . 다른 곳에서 언급 된 RFC는 CSV의 표준이 아니며, MIME 내에서 CSV를 사용하기위한 RFC이며 MIME 외부에서 쓸모 없게 만드는 기존의 불필요한 제한 사항이 포함되어 있습니다.

내가 보지 못했던 많은 CSV 모듈은 여러 줄을 단일 필드로 인코딩 할 수 있다는 사실입니다. 즉, 각 줄이 별도의 레코드라고 가정 할 수 없으므로 줄 바꿈을 허용하지 않아도됩니다 데이터를 처리하거나이를 처리 할 준비를하십시오.


40

문자열을 큰 따옴표로 묶습니다. 그것은 일반적으로 Excel이하는 일 입니다.

알라 엘리,

큰 따옴표를 두 개의 큰 따옴표로 이스케이프합니다. 예 : "test1", "foo" "bar", "test2"


인용 된 식별자와 기본적으로 동일한 개념
Bob The Janitor

1
큰 따옴표를 두 개의 큰 따옴표로 이스케이프합니다. 예 : "test1", "foo" "bar", "test2"
Eli

그냥 문자열 주위에 따옴표를 넣어은 "이 쉼표 바로 뒤에 때 작동하지 않습니다
MondKin

9

필드를 큰 따옴표로 묶을 수 있습니다. 다른 특수 문자 (큰 따옴표)를 추가하기 때문에이 방법이 마음에 들지 않습니다. 이스케이프 문자 (일반적으로 백 슬래시)를 정의하고 무언가를 이스케이프해야 할 때마다 사용하십시오.

데이터, 더 많은 데이터, 더 많은 데이터 \, 심지어 더

따옴표와 일치시킬 필요가 없으며 구문 분석 할 예외가 더 적습니다. 이렇게하면 코드도 단순화됩니다.


3
실제로 "\"가 포함 된 항목이 있으면 빠르고 더럽지 만 작동하지 않습니다.
Sarp Kaya

1
Sarp, 그래서 이중 \\는 이스케이프 된 백 슬래시입니다. 이제 다른 특수 문자가되었습니다.
Grungondola

1
이것은 작동하지만 CSV는 아닙니다. 그것은이다 DSV 값 .
TRiG

8

잘 구성된 CSV (.net)를 처리하기 위해 nuget을 통해 사용할 수있는 라이브러리가 있습니다 -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라이브러리를 사용 하여 OP의 문제를 해결하는 방법의 예를 포함시킨 것이 바람직합니다 .
George Stocker

.Net의 거의 모든 것이 "도우미"가되어야하는 이유는 ... "관리자"와 같이 거의 의미가 없습니다.
bytedev

5

하포의 답변에 대한 나의 의견에서 언급했듯이, 그의 해결책은 훌륭하고 대부분의 경우 작동하지만 일부 시나리오에서는 쉼표가 서로 직접 인접하여있는 경우 쉼표로 분할되지 않습니다.

이것은 정규식 문자열이 예상치 못한 문자열로 동작하기 때문입니다. 이 동작을 올바르게 수행하려면 정규식 이스케이프를 사용하지 않고 정규식 문자열의 모든 "문자를 수동으로 이스케이프해야합니다.

즉. 정규식은 수동 이스케이프를 사용하여 다음과 같아야합니다.

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

이것은로 번역 ",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))"

vertabim 문자열을 사용 @",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))"하면 정규식을 디버깅하는지 확인할 수있는 것처럼 다음과 같이 작동합니다.

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

요약하면, 나는 harpo의 솔루션을 추천하지만,이 작은 문제를 조심하십시오!

이 오류가 발생하면 (알려진 열 수가있는 경우) 알려주는 약간의 옵션 안전 장치를 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

하지가 [^""]같은 [^"]? 문자 클래스 사양 내에서 문자를 복제하는 것은 중복 적입니다.
Minh Tran

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은 이미 수행합니다.
Christopher King


4

경우에 당신은에있어 * nix에서 스크립트 시스템 에 액세스 할 수 있습니다 sed하나 이상있을 수 있습니다 만에서 원하지 않는 쉼표 특정 필드 당신의 CSV, 당신은 그들을 둘러싸하기 위해 다음과 같은 한 줄을 사용할 수 있습니다 "RFC4180 섹션 2 제안 :

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

원치 않는 쉼표가 어느 필드에 있는지에 따라 정규식의 캡처 그룹 (및 대체)을 변경 / 확장해야합니다.
위의 예는 네 번째 필드 (6 개 중)를 따옴표로 묶습니다.

여기에 이미지 설명을 입력하십시오

--in-place-option 과 함께 이러한 변경 사항을 파일에 직접 적용 할 수 있습니다.

올바른 정규 표현식을 "빌드"하기 위해 따라야 할 간단한 원칙이 있습니다.

  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 사용)에 대한보다 교육적인 연습에 관심이 있다면 Julian Bucknall 의이 기사 를 확인하십시오 . 나는 기사를 훨씬 더 작은 문제로 나눌 수 없기 때문에이 기사를 좋아한다. 먼저 문법을 만들고 일단 문법이 좋으면 문법을 코드로 변환하는 것은 비교적 쉽고 체계적인 프로세스입니다.

이 기사에서는 C #을 사용하고 하단에 코드를 다운로드 할 수있는 링크가 있습니다.


1

깔끔한 작은 해결 방법이 있습니다.

대신 그리스어 하위 숫자 부호를 사용할 수 있습니다 (U + 0375)

이렇게 보입니다

이 방법을 사용하면 많은 리소스를 절약 할 수 있습니다.


1

NuGet에서 SoftCircuits.CsvParser 를 사용 하십시오 . 그것은 당신을 위해 모든 세부 사항을 처리하고 매우 큰 파일을 효율적으로 처리합니다. 또한 필요한 경우 열을 객체 속성에 매핑하여 객체를 가져 오거나 내보낼 수도 있습니다. 또한 내 테스트에서 인기있는 CsvHelper보다 거의 4 배 빠릅니다.


0

이것은 일반적인 관행에 관한 것이므로 엄지 손가락의 규칙부터 시작하겠습니다.

  1. CSV를 사용하지 말고 대신 XML을 라이브러리와 함께 사용하여 xml 파일을 읽고 씁니다.

  2. CSV를 사용해야하는 경우 올바르게 수행하고 무료 라이브러리를 사용하여 CSV 파일을 구문 분석하고 저장하십시오.

1)을 정당화하기 위해 대부분의 CSV 파서는 인코딩을 인식하지 못하므로 US-ASCII를 다루지 않으면 문제가 있습니다. 예를 들어 Excel 2002는 인코딩에 대한 메모없이 CSV를 로컬 인코딩으로 저장합니다. CSV 표준은 널리 채택되지 않았습니다. (. 반면 XML 표준은 잘 채택되었으며 인코딩을 잘 처리합니다.

2) 정당화하기 위해, 거의 모든 언어에 대한 수많은 csv 파서가 있으므로 솔루션이 매우 단순 해 보이지만 바퀴를 재발 명 할 필요가 없습니다.

몇 가지 예를 들면 다음과 같습니다.

  • 파이썬의 경우 csv 모듈 에서 빌드

  • 펄 체크 CPAN 및 텍스트 :: CSV

  • fgetcsv / fputcsv 함수에서 PHP 사용 빌드

  • Java 점검 SuperCVS 라이브러리 용

임베디드 장치에서 구문 분석하지 않으려는 경우 직접 손으로 구현할 필요가 없습니다.


12
XML이 항상 정답은 아닙니다. CSV는 밀도가 높은 테이블 형식 데이터 (예 : 스프레드 시트)가 많은 경우 작업에 적합한 형식입니다. 이러한 태그는 많은 오버 헤드를 발생 시키며 각 행의 형식이 동일하면 각 값이 무엇을 나타내는 지 명시 할 필요가 없습니다. XML은 복잡한 계층 적 데이터 또는 선택적 필드가있는 레코드가있는 경우 유용합니다. 항상 그런 것은 아닙니다.
Adam Jaskiewicz 2009

이론적으로 "태그"에는 약간의 오버 헤드가 발생하지만 문제가되는 실제 응용 프로그램은 생각할 수 없습니다. 실제적인 예가 있습니까? 데이터 작업을하려면 csv 대신 데이터베이스를 사용해야합니다. 데이터 직렬화 (백업, 데이터 교환)에 대해 이야기 할 경우 5 일 대신 1 주일이 걸리는 경우 문제가됩니까?
Piotr Czapla

2
기본적으로 테이블로 가장 잘 표현되는 데이터가있는 상황. 자주 샘플링하는 12 개의 서로 다른 센서의 데이터가 있고 그 시간에 각 센서의 타임 스탬프와 값을 기록한다고 가정 해보십시오. 각 레코드는 동일합니다 : 타임 스탬프, 센서 0, 센서 1, ... 센서 11. XML은 복잡하고 불규칙적 인 데이터를 표현하는 데는 좋지만 모든 상황에 맞지 않는 다소 무거운 형식입니다. KISS
Adam Jaskiewicz

10
어떤 사람들은 문제를보고 "알아요, XML을 사용하겠습니다!"라고 말합니다. 이제 두 가지 문제가 있습니다.
Adam Jaskiewicz 2009

나는 XML이 모든 것에 대한 대답이 아니라는 것에 전적으로 동의한다. 특히 데이터베이스 교체 나 구성 파일로는 적합하지 않습니다. 그러나 여기서 질문은 XML이 설계된 데이터 교환에 관한 것이었다.
Piotr Czapla

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
}

바꾸기 기능에서 두 번째 쉼표로 보이는 문자는 10218입니다.

ASCII 전용 텍스트 리더가있는 클라이언트가있는 경우이 decima 8218 문자는 쉼표처럼 보이지 않습니다. 이것이 당신의 경우라면, RFC 4128 당 큰 따옴표가있는 쉼표 (또는 세미콜론)로 필드를 둘러 쌀 것을 권장합니다 : https://tools.ietf.org/html/rfc4180


0

일반적으로 쉼표 나 특수 문자를 사용할 수있는 필드를 URL 인코딩합니다. 그런 다음 시각적 매체에서 사용 / 표시 될 때이를 디코딩하십시오.

(쉼표는 % 2C가 됨)

모든 언어에는 문자열을 URL 인코딩 및 디코딩하는 방법이 있어야합니다.

예를 들어, 자바에서

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

나는 이것이 매우 일반적인 해결책이라는 것을 알고 있으며 사용자가 csv 파일의 내용을 수동으로보고 싶은 상황에는 이상적이지 않을 수 있습니다.


0

일반적으로 CSV 파일 구문 분석 루틴에서이 작업을 수행합니다. 'line'변수가 CSV 파일 내에서 한 줄이고 모든 열의 값이 큰 따옴표로 묶여 있다고 가정하십시오. 아래 두 줄이 실행되면 'values'컬렉션에 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에서 여러 색상으로 표시되지 않습니까? 4 칸 들여 쓰기
user1451111


0

내가 찾은 가장 간단한 솔루션은 LibreOffice이 사용하는 솔루션입니다.

  1. 모든 리터럴 "
  2. 문자열을 큰 따옴표로 묶습니다.

Excel에서 사용하는 것을 사용할 수도 있습니다.

  1. 모든 리터럴 """
  2. 문자열을 큰 따옴표로 묶습니다.

다른 사람들은 위의 2 단계 만 권장하지만 CSV가 읽는 것처럼 문자열이있는 단일 열을 원하는 CSV와 같이 "a 다음에 a가 오는 행에서는 작동하지 않습니다 .,hello",world

"hello",world"

어떤 두 개의 열이있는 행으로 해석됩니다 helloworld"


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

CSV 파싱 데모를 위해 dummy.csv 파일이 있습니다.

모든 언어로 작성된 앱에서 쉽고 간단하게 복제 할 수 있지만 reactJS 내에서 사용했습니다.


0

.csv 파일에 쉼표를 표시하는 방법을 보여주는 예제가 도움이 될 수 있습니다. 다음과 같이 간단한 텍스트 파일을 작성하십시오.

이 텍스트 파일을 접미사 ".csv"가있는 텍스트 파일로 저장하고 Windows 10의 Excel 2000에서 엽니 다.

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", 첫 번째 따옴표로 인해 공간 belore로 인해 Excel 2000에서 실패 aa, bb, cc, "d, d" 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에서도 두 번째 인용 전후의 공백이 있어도 작동합니다.

규칙 : .csv 파일의 셀 (필드)에 쉼표를 표시하려는 경우 : "큰 따옴표로 필드를 시작하고 종료하지만 첫 번째 따옴표 앞의 공백은 피하십시오"


-1

이 문제에 대한 가장 쉬운 해결책은 고객이 CSV로 Excel을 연 다음 Ctrl + r을 사용하여 모든 쉼표를 원하는 식별자로 바꾸는 것입니다. 이는 고객에게 매우 쉽고 선택한 구분 기호를 읽으려면 코드를 한 번만 변경하면됩니다.


누가 Excel을 가지고 있다고 말합니까? 실제로 누가 업로드를하고있는 사람이라고 말합니까? ...
bytedev

-3

탭 문자 (\ t)를 사용하여 필드를 구분하십시오.


4
-1 누군가가 자신의 가치에 따라 탭을 사용할 때까지는 그 다음 질문을하는 사람이 가진 문제에 대한 귀하의 권리로 돌아갑니다. 하나의 구분 문자를 다른 문자로 바꾸면 문제가 해결되지 않습니다.
bytedev

무의미한 말. 사람들은 데이터 입력에 탭을 입력 할 수 없습니다. 대부분의 경우 데이터 입력 포인트를 다음 필드로 이동합니다.
Pierre

6
"사람은 데이터 입력에 탭을 입력 할 수 없습니다".... 정말입니까? A) 물론 사람은 입력 필드에 탭을 넣을 수 있습니다. B) 누가 데이터가 GUI에서 왔는지 말합니까? C) 누가 데이터를 입력하고 있다고 말하는가?
bytedev
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.