program tip

데이터에 쉼표가 포함 된 Javascript로 CSV 문자열을 구문 분석하려면 어떻게해야합니까?

radiobox 2020. 10. 11. 10:04
반응형

데이터에 쉼표가 포함 된 Javascript로 CSV 문자열을 구문 분석하려면 어떻게해야합니까?


다음 유형의 문자열이 있습니다.

var string = "'string, duppi, du', 23, lala"

각 쉼표에서 문자열을 배열로 나누고 싶지만 작은 따옴표 밖에있는 쉼표 만 있습니다.

분할에 적합한 정규식을 찾을 수 없습니다.

string.split(/,/)

나에게 줄 것이다

["'string", " duppi", " du'", " 23", " lala"]

그러나 결과는 다음과 같아야합니다.

["string, duppi, du", "23", "lala"]

크로스 브라우저 솔루션이 있습니까?


부인 성명

2014-12-01 업데이트 : 아래 답변은 매우 구체적인 CSV 형식에만 적용됩니다. 의견에서 DG가 올바르게 지적했듯이이 솔루션은 CSV의 RFC 4180 정의에 맞지 않으며 MS Excel 형식에도 맞지 않습니다. 이 솔루션은 문자열에 이스케이프 된 따옴표와 쉼표가 포함될 수있는 문자열 유형의 혼합을 포함하는 하나의 (비표준) CSV 입력 행을 구문 분석하는 방법을 보여줍니다.

비표준 CSV 솔루션

austincheney가 올바르게 지적했듯이, 이스케이프 된 문자를 포함 할 수있는 따옴표로 묶인 문자열을 올바르게 처리하려면 문자열을 처음부터 끝까지 구문 분석해야합니다. 또한 OP는 "CSV 문자열"이 실제로 무엇인지 명확하게 정의하지 않습니다. 먼저 유효한 CSV 문자열과 개별 값을 구성하는 항목을 정의해야합니다.

주어진 : "CSV 문자열"정의

이 설명을 위해 "CSV 문자열"은 0 개 이상의 값으로 구성되며 여러 값은 쉼표로 구분됩니다. 각 값은 다음으로 구성 될 수 있습니다.

  1. 큰 따옴표로 묶인 문자열. (이스케이프 처리되지 않은 작은 따옴표를 포함 할 수 있습니다.)
  2. 작은 따옴표로 묶인 문자열. (이스케이프 처리되지 않은 큰 따옴표를 포함 할 수 있습니다.)
  3. 인용되지 않은 문자열입니다. (따옴표, 쉼표 또는 백 슬래시를 포함 할 수 없습니다.)
  4. 빈 값. (모두 공백 값은 비어있는 것으로 간주됩니다.)

규칙 / 참고 :

  • 인용 된 값에는 쉼표가 포함될 수 있습니다.
  • 인용 된 값은 이스케이프 된 모든 것을 포함 할 수 있습니다 'that\'s cool'.
  • 따옴표, 쉼표 또는 백 슬래시가 포함 된 값은 따옴표로 묶어야합니다.
  • 선행 또는 후행 공백이 포함 된 값은 따옴표로 묶어야합니다.
  • 백 슬래시는 모두에서 제거됩니다 : \'작은 따옴표로 묶인 값.
  • 백 슬래시는 모두에서 제거됩니다 : \"큰 따옴표로 묶인 값.
  • 인용되지 않은 문자열은 선행 및 후행 공백이 제거됩니다.
  • 쉼표 구분 기호에 인접한 공백이있을 수 있습니다 (무시 됨).

찾기:

유효한 CSV 문자열 (위에 정의 된대로)을 문자열 값의 배열로 변환하는 JavaScript 함수입니다.

해결책:

이 솔루션에서 사용하는 정규식은 복잡합니다. 그리고 (IMHO) 모든 중요하지 않은 정규식은 많은 주석과 들여 쓰기와 함께 자유 간격 모드로 표시되어야합니다. 안타깝게도 JavaScript는 자유 간격 모드를 허용하지 않습니다. 따라서이 솔루션에 의해 구현 된 정규식은 먼저 기본 정규식 구문으로 표시됩니다 (Python의 편리한 : r'''...'''원시 다중 행 문자열 구문을 사용하여 표현됨 ).

먼저 여기에 CVS 문자열이 위의 요구 사항을 충족하는지 확인하는 정규식이 있습니다.

"CSV 문자열"의 유효성을 검사하는 정규식 :

re_valid = r"""
# Validate a CSV string having single, double or un-quoted values.
^                                   # Anchor to start of string.
\s*                                 # Allow whitespace before value.
(?:                                 # Group for value alternatives.
  '[^'\\]*(?:\\[\S\s][^'\\]*)*'     # Either Single quoted string,
| "[^"\\]*(?:\\[\S\s][^"\\]*)*"     # or Double quoted string,
| [^,'"\s\\]*(?:\s+[^,'"\s\\]+)*    # or Non-comma, non-quote stuff.
)                                   # End group of value alternatives.
\s*                                 # Allow whitespace after value.
(?:                                 # Zero or more additional values
  ,                                 # Values separated by a comma.
  \s*                               # Allow whitespace before value.
  (?:                               # Group for value alternatives.
    '[^'\\]*(?:\\[\S\s][^'\\]*)*'   # Either Single quoted string,
  | "[^"\\]*(?:\\[\S\s][^"\\]*)*"   # or Double quoted string,
  | [^,'"\s\\]*(?:\s+[^,'"\s\\]+)*  # or Non-comma, non-quote stuff.
  )                                 # End group of value alternatives.
  \s*                               # Allow whitespace after value.
)*                                  # Zero or more additional values
$                                   # Anchor to end of string.
"""

문자열이 위의 정규식과 일치하면 해당 문자열은 유효한 CSV 문자열 (이전에 언급 한 규칙에 따라)이며 다음 정규식을 사용하여 구문 분석 할 수 있습니다. 그런 다음 다음 정규식을 사용하여 CSV 문자열에서 하나의 값을 일치시킵니다. 더 이상 일치하는 항목이없고 모든 값이 구문 분석 될 때까지 반복적으로 적용됩니다.

유효한 CSV 문자열에서 하나의 값을 구문 분석하는 정규식 :

re_value = r"""
# Match one value in valid CSV string.
(?!\s*$)                            # Don't match empty last value.
\s*                                 # Strip whitespace before value.
(?:                                 # Group for value alternatives.
  '([^'\\]*(?:\\[\S\s][^'\\]*)*)'   # Either $1: Single quoted string,
| "([^"\\]*(?:\\[\S\s][^"\\]*)*)"   # or $2: Double quoted string,
| ([^,'"\s\\]*(?:\s+[^,'"\s\\]+)*)  # or $3: Non-comma, non-quote stuff.
)                                   # End group of value alternatives.
\s*                                 # Strip whitespace after value.
(?:,|$)                             # Field ends on comma or EOS.
"""

이 정규식이 일치하지 않는 특별한 경우 값이 하나 있습니다. 해당 값이 비어있을 때 가장 마지막 값입니다. 이 특별한 "빈 마지막 값" 케이스는 뒤에 오는 js 함수에 의해 테스트되고 처리됩니다.

CSV 문자열을 구문 분석하는 JavaScript 함수 :

// Return array of string values, or NULL if CSV string not well formed.
function CSVtoArray(text) {
    var re_valid = /^\s*(?:'[^'\\]*(?:\\[\S\s][^'\\]*)*'|"[^"\\]*(?:\\[\S\s][^"\\]*)*"|[^,'"\s\\]*(?:\s+[^,'"\s\\]+)*)\s*(?:,\s*(?:'[^'\\]*(?:\\[\S\s][^'\\]*)*'|"[^"\\]*(?:\\[\S\s][^"\\]*)*"|[^,'"\s\\]*(?:\s+[^,'"\s\\]+)*)\s*)*$/;
    var re_value = /(?!\s*$)\s*(?:'([^'\\]*(?:\\[\S\s][^'\\]*)*)'|"([^"\\]*(?:\\[\S\s][^"\\]*)*)"|([^,'"\s\\]*(?:\s+[^,'"\s\\]+)*))\s*(?:,|$)/g;
    // Return NULL if input string is not well formed CSV string.
    if (!re_valid.test(text)) return null;
    var a = [];                     // Initialize array to receive values.
    text.replace(re_value, // "Walk" the string using replace with callback.
        function(m0, m1, m2, m3) {
            // Remove backslash from \' in single quoted values.
            if      (m1 !== undefined) a.push(m1.replace(/\\'/g, "'"));
            // Remove backslash from \" in double quoted values.
            else if (m2 !== undefined) a.push(m2.replace(/\\"/g, '"'));
            else if (m3 !== undefined) a.push(m3);
            return ''; // Return empty string.
        });
    // Handle special case of empty last value.
    if (/,\s*$/.test(text)) a.push('');
    return a;
};

입력 및 출력 예 :

다음 예에서는 중괄호를 사용하여 {result strings}. (이것은 선행 / 후행 공백과 길이가 0 인 문자열을 시각화하는 데 도움이됩니다.)

// Test 1: Test string from original question.
var test = "'string, duppi, du', 23, lala";
var a = CSVtoArray(test);
/* Array hes 3 elements:
    a[0] = {string, duppi, du}
    a[1] = {23}
    a[2] = {lala} */
// Test 2: Empty CSV string.
var test = "";
var a = CSVtoArray(test);
/* Array hes 0 elements: */
// Test 3: CSV string with two empty values.
var test = ",";
var a = CSVtoArray(test);
/* Array hes 2 elements:
    a[0] = {}
    a[1] = {} */
// Test 4: Double quoted CSV string having single quoted values.
var test = "'one','two with escaped \' single quote', 'three, with, commas'";
var a = CSVtoArray(test);
/* Array hes 3 elements:
    a[0] = {one}
    a[1] = {two with escaped ' single quote}
    a[2] = {three, with, commas} */
// Test 5: Single quoted CSV string having double quoted values.
var test = '"one","two with escaped \" double quote", "three, with, commas"';
var a = CSVtoArray(test);
/* Array hes 3 elements:
    a[0] = {one}
    a[1] = {two with escaped " double quote}
    a[2] = {three, with, commas} */
// Test 6: CSV string with whitespace in and around empty and non-empty values.
var test = "   one  ,  'two'  ,  , ' four' ,, 'six ', ' seven ' ,  ";
var a = CSVtoArray(test);
/* Array hes 8 elements:
    a[0] = {one}
    a[1] = {two}
    a[2] = {}
    a[3] = { four}
    a[4] = {}
    a[5] = {six }
    a[6] = { seven }
    a[7] = {} */

추가 참고 사항 :

이 솔루션을 사용하려면 CSV 문자열이 "유효"해야합니다. 예를 들어 따옴표가없는 값에는 백 슬래시 또는 따옴표가 포함될 수 없습니다. 예를 들어 다음 CSV 문자열은 유효하지 않습니다.

var invalid1 = "one, that's me!, escaped \, comma"

하위 문자열이 작은 따옴표 또는 큰 따옴표 값으로 표현 될 수 있기 때문에 이것은 실제로 제한이 아닙니다. 또한이 솔루션은 "쉼표로 구분 된 값"에 대한 하나의 가능한 정의 만 나타냅니다.

편집 : 2014-05-19 : 면책 조항 추가. 편집 : 2014-12-01 : 면책 조항을 맨 위로 이동했습니다.


RFC 4180 솔루션

형식이 RFC 4180을 따르지 않기 때문에 문제의 문자열은 해결되지 않습니다. 허용되는 인코딩은 큰 따옴표를 사용하여 큰 따옴표를 이스케이프하는 것입니다. 아래 솔루션은 Google 스프레드 시트의 CSV 파일 d / l에서 올바르게 작동합니다.

업데이트 (2017 년 3 월)

한 줄을 구문 분석하는 것은 잘못되었습니다. RFC 4180에 따르면 필드에 CRLF가 포함될 수 있으며 이로 인해 모든 행 판독기가 CSV 파일을 중단하게됩니다. 다음은 CSV 문자열을 구문 분석하는 업데이트 된 버전입니다.

'use strict';

function csvToArray(text) {
    let p = '', row = [''], ret = [row], i = 0, r = 0, s = !0, l;
    for (l of text) {
        if ('"' === l) {
            if (s && l === p) row[i] += l;
            s = !s;
        } else if (',' === l && s) l = row[++i] = '';
        else if ('\n' === l && s) {
            if ('\r' === p) row[i] = row[i].slice(0, -1);
            row = ret[++r] = [l = '']; i = 0;
        } else row[i] += l;
        p = l;
    }
    return ret;
};

let test = '"one","two with escaped """" double quotes""","three, with, commas",four with no quotes,"five with CRLF\r\n"\r\n"2nd line one","two with escaped """" double quotes""","three, with, commas",four with no quotes,"five with CRLF\r\n"';
console.log(csvToArray(test));

오래된 답변

(단일 라인 솔루션)

function CSVtoArray(text) {
    let ret = [''], i = 0, p = '', s = true;
    for (let l in text) {
        l = text[l];
        if ('"' === l) {
            s = !s;
            if ('"' === p) {
                ret[i] += '"';
                l = '-';
            } else if ('' === p)
                l = '-';
        } else if (s && ',' === l)
            l = ret[++i] = '';
        else
            ret[i] += l;
        p = l;
    }
    return ret;
}
let test = '"one","two with escaped """" double quotes""","three, with, commas",four with no quotes,five for fun';
console.log(CSVtoArray(test));

재미를 위해 배열에서 CSV를 만드는 방법은 다음과 같습니다.

function arrayToCSV(row) {
    for (let i in row) {
        row[i] = row[i].replace(/"/g, '""');
    }
    return '"' + row.join('","') + '"';
}

let row = [
  "one",
  "two with escaped \" double quote",
  "three, with, commas",
  "four with no quotes (now has)",
  "five for fun"
];
let text = arrayToCSV(row);
console.log(text);


http://en.wikipedia.org/wiki/Comma-separated_values 에서 RFC 4180 예제를 처리하는 PEG (.js) 문법 :

start
  = [\n\r]* first:line rest:([\n\r]+ data:line { return data; })* [\n\r]* { rest.unshift(first); return rest; }

line
  = first:field rest:("," text:field { return text; })*
    & { return !!first || rest.length; } // ignore blank lines
    { rest.unshift(first); return rest; }

field
  = '"' text:char* '"' { return text.join(''); }
  / text:[^\n\r,]* { return text.join(''); }

char
  = '"' '"' { return '"'; }
  / [^"]

http://jsfiddle.net/knvzk/10 또는 https://pegjs.org/online 에서 테스트 하십시오 .

https://gist.github.com/3362830 에서 생성 된 파서를 다운로드합니다 .


Google 스프레드 시트의 셀을 웹 앱으로 복사하려는 매우 구체적인 사용 사례가있었습니다. 셀에는 큰 따옴표와 개행 문자가 포함될 수 있습니다. 복사 및 붙여 넣기를 사용하면 셀이 탭 문자로 구분되고 홀수 데이터가있는 셀은 큰 따옴표로 묶입니다. 이 주요 솔루션, regexp를 사용하는 링크 된 기사, Jquery-CSV 및 CSVToArray를 시도했습니다. http://papaparse.com/ 바로 사용할 수있는 유일한 방법입니다. 기본 자동 감지 옵션이있는 Google 스프레드 시트를 사용하면 복사 및 붙여 넣기가 원활합니다.


나는 FakeRainBrigand의 대답을 좋아했지만 몇 가지 문제가 있습니다. 따옴표와 쉼표 사이의 공백을 처리 할 수 ​​없으며 2 개의 연속 쉼표를 지원하지 않습니다. 나는 그의 대답을 편집하려고 시도했지만 내 코드를 이해하지 못한 검토 자에 의해 편집이 거부되었습니다. 다음은 FakeRainBrigand 코드의 내 버전입니다. 바이올린도 있습니다 : http://jsfiddle.net/xTezm/46/

String.prototype.splitCSV = function() {
        var matches = this.match(/(\s*"[^"]+"\s*|\s*[^,]+|,)(?=,|$)/g);
        for (var n = 0; n < matches.length; ++n) {
            matches[n] = matches[n].trim();
            if (matches[n] == ',') matches[n] = '';
        }
        if (this[0] == ',') matches.unshift("");
        return matches;
}

var string = ',"string, duppi, du" , 23 ,,, "string, duppi, du",dup,"", , lala';
var parsed = string.splitCSV();
alert(parsed.join('|'));

목록에 하나 더 추가하면 위의 모든 것이 충분히 "KISS"가 아니라는 것을 알기 때문입니다.

이것은 정규식을 사용하여 쉼표 또는 줄 바꿈을 찾고 인용 된 항목을 건너 뜁니다. 바라건대 이것은 누비들이 스스로 읽을 수있는 내용입니다. splitFinder정규 표현식은 (바이 분할 않는 세 가지가 있습니다 |)

  1. , -쉼표를 찾습니다.
  2. \r?\n -새 줄을 찾습니다 (수출자가 좋은 경우 캐리지 리턴 포함)
  3. "(\\"|[^"])*?"-쉼표와 줄 바꿈은 중요하지 않기 때문에 따옴표로 묶인 것은 건너 뜁니다. \\"인용 된 항목에 이스케이프 된 인용문 이 있으면 끝 인용문을 찾기 전에 캡처됩니다.

const splitFinder = /,|\r?\n|"(\\"|[^"])*?"/g;

function csvTo2dArray(parseMe) {
  let currentRow = [];
  const rowsOut = [currentRow];
  let lastIndex = splitFinder.lastIndex = 0;
  
  // add text from lastIndex to before a found newline or comma
  const pushCell = (endIndex) => {
    endIndex = endIndex || parseMe.length;
    const addMe = parseMe.substring(lastIndex, endIndex);
    // remove quotes around the item
    currentRow.push(addMe.replace(/^"|"$/g, ""));
    lastIndex = splitFinder.lastIndex;
  }


  let regexResp;
  // for each regexp match (either comma, newline, or quoted item)
  while (regexResp = splitFinder.exec(parseMe)) {
    const split = regexResp[0];

    // if it's not a quote capture, add an item to the current row
    // (quote captures will be pushed by the newline or comma following)
    if (split.startsWith(`"`) === false) {
      const splitStartIndex = splitFinder.lastIndex - split.length;
      pushCell(splitStartIndex);

      // then start a new row if newline
      const isNewLine = /^\r?\n$/.test(split);
      if (isNewLine) { rowsOut.push(currentRow = []); }
    }
  }
  // make sure to add the trailing text (no commas or newlines after)
  pushCell();
  return rowsOut;
}

const rawCsv = `a,b,c\n"test\r\n","comma, test","\r\n",",",\nsecond,row,ends,with,empty\n"quote\"test"`
const rows = csvTo2dArray(rawCsv);
console.log(rows);


따옴표 구분 기호를 큰 따옴표로 지정할 수있는 경우 이는 CSV 데이터 구문 분석 을위한 JavaScript 코드 의 복제본입니다 .

먼저 모든 작은 따옴표를 큰 따옴표로 번역 할 수 있습니다.

string = string.replace( /'/g, '"' );

... 또는 큰 따옴표 대신 작은 따옴표를 인식하도록 해당 질문의 정규식을 편집 할 수 있습니다.

// Quoted fields.
"(?:'([^']*(?:''[^']*)*)'|" +

그러나 이것은 귀하의 질문에서 명확하지 않은 특정 마크 업을 가정합니다. 귀하의 질문에 대한 저의 의견에 따라 마크 업의 다양한 가능성이 무엇인지 명확히하십시오.


내 대답은 귀하의 입력이 웹 소스의 코드 / 콘텐츠를 반영한 ​​것으로 가정합니다. 여기서 작은 따옴표와 큰 따옴표 문자는 이스케이프되지 않은 일치 집합으로 발생하는 경우 완전히 호환됩니다.

이를 위해 정규식을 사용할 수 없습니다. 분할하려는 문자열을 분석하려면 실제로 마이크로 파서를 작성해야합니다. 이 대답을 위해 문자열에서 인용 된 부분을 하위 문자열이라고 부를 것입니다. 특별히 줄을 가로 질러 걸어야합니다. 다음 경우를 고려하십시오.

var a = "some sample string with \"double quotes\" and 'single quotes' and some craziness like this: \\\" or \\'",
    b = "sample of code from JavaScript with a regex containing a comma /\,/ that should probably be ignored.";

이 경우 문자 패턴에 대한 입력을 분석하여 하위 문자열이 시작되거나 끝나는 위치를 전혀 알 수 없습니다. 대신 따옴표 문자가 따옴표 문자로 사용되는지, 자체적으로 따옴표가 없는지, 따옴표 문자가 이스케이프 뒤에 있지 않은지 여부를 결정하는 논리를 작성해야합니다.

나는 당신을 위해 복잡한 수준의 코드를 작성하지 않을 것입니다. 그러나 당신은 당신이 필요로하는 패턴을 가진 내가 최근에 작성한 것을 볼 수 있습니다. 이 코드는 쉼표와 관련이 없지만, 그렇지 않으면 코드를 작성할 때 따라갈 수있을만큼 유효한 마이크로 파서입니다. 다음 애플리케이션의 asifix 기능을 살펴보십시오.

https://github.com/austincheney/Pretty-Diff/blob/master/fulljsmin.js


사람들은 이에 대해 RegEx에 반대하는 것처럼 보였습니다. 왜?

(\s*'[^']+'|\s*[^,]+)(?=,|$)

여기에 코드가 있습니다. 나는 또한 바이올린을 만들었다 .

String.prototype.splitCSV = function(sep) {
  var regex = /(\s*'[^']+'|\s*[^,]+)(?=,|$)/g;
  return matches = this.match(regex);    
}

var string = "'string, duppi, du', 23, 'string, duppi, du', lala";
var parsed = string.splitCSV();
alert(parsed.join('|'));

csv를 문자열로 읽는 동안 문자열 사이에 null 값이 포함되어 있으므로 \ 0 한 줄씩 시도해보십시오 .

stringLine = stringLine.replace( /\0/g, "" );

이 답변 을 보완하기 위해

다른 따옴표로 이스케이프 된 따옴표를 구문 분석해야하는 경우 예를 들면 다음과 같습니다.

"some ""value"" that is on xlsx file",123

당신이 사용할 수있는

function parse(text) {
  const csvExp = /(?!\s*$)\s*(?:'([^'\\]*(?:\\[\S\s][^'\\]*)*)'|"([^"\\]*(?:\\[\S\s][^"\\]*)*)"|"([^""]*(?:"[\S\s][^""]*)*)"|([^,'"\s\\]*(?:\s+[^,'"\s\\]+)*))\s*(?:,|$)/g;

  const values = [];

  text.replace(csvExp, (m0, m1, m2, m3, m4) => {
    if (m1 !== undefined) {
      values.push(m1.replace(/\\'/g, "'"));
    }
    else if (m2 !== undefined) {
      values.push(m2.replace(/\\"/g, '"'));
    }
    else if (m3 !== undefined) {
      values.push(m3.replace(/""/g, '"'));
    }
    else if (m4 !== undefined) {
      values.push(m4);
    }
    return '';
  });

  if (/,\s*$/.test(text)) {
    values.push('');
  }

  return values;
}

CSV 파일을 구문 분석해야 할 때도 동일한 유형의 문제에 직면했습니다. 파일에는 ','를 포함하는 열 주소가 있습니다.
해당 CSV를 JSON으로 파싱 한 후 JSON 파일로 변환하는 동안 키 매핑이 일치하지 않습니다.
나는 baby parsecsvtojson 같은 파일 및 라이브러리를 구문 분석하는 데 노드를 사용했습니다. 파일의
예-

address,pincode
foo,baar , 123456

JSON에서 아기 구문 분석을 사용하지 않고 직접 구문 분석하는 동안

[{
 address: 'foo',
 pincode: 'baar',
 'field3': '123456'
}]

그래서 모든 필드에서 다른 구분 기호로 쉼표 (,)를 제거하는 코드를 작성했습니다.

/*
 csvString(input) = "address, pincode\\nfoo, bar, 123456\\n"
 output = "address, pincode\\nfoo {YOUR DELIMITER} bar, 123455\\n"
*/
const removeComma = function(csvString){
    let delimiter = '|'
    let Baby = require('babyparse')
    let arrRow = Baby.parse(csvString).data;
    /*
      arrRow = [ 
      [ 'address', 'pincode' ],
      [ 'foo, bar', '123456']
      ]
    */
    return arrRow.map((singleRow, index) => {
        //the data will include 
        /* 
        singleRow = [ 'address', 'pincode' ]
        */
        return singleRow.map(singleField => {
            //for removing the comma in the feild
            return singleField.split(',').join(delimiter)
        })
    }).reduce((acc, value, key) => {
        acc = acc +(Array.isArray(value) ?
         value.reduce((acc1, val)=> {
            acc1 = acc1+ val + ','
            return acc1
        }, '') : '') + '\n';
        return acc;
    },'')
}

반환 된 함수는 csvtojson 라이브러리에 전달 될 수 있으므로 결과를 사용할 수 있습니다.

const csv = require('csvtojson')

let csvString = "address, pincode\\nfoo, bar, 123456\\n"
let jsonArray = []
modifiedCsvString = removeComma(csvString)
csv()
  .fromString(modifiedCsvString)
  .on('json', json => jsonArray.push(json))
  .on('end', () => {
    /* do any thing with the json Array */
  })
이제 다음과 같은 출력을 얻을 수 있습니다.

[{
  address: 'foo, bar',
  pincode: 123456
}]

이 블로그 게시물 에 따르면 이 함수는 다음을 수행해야합니다.

String.prototype.splitCSV = function(sep) {
  for (var foo = this.split(sep = sep || ","), x = foo.length - 1, tl; x >= 0; x--) {
    if (foo[x].replace(/'\s+$/, "'").charAt(foo[x].length - 1) == "'") {
      if ((tl = foo[x].replace(/^\s+'/, "'")).length > 1 && tl.charAt(0) == "'") {
        foo[x] = foo[x].replace(/^\s*'|'\s*$/g, '').replace(/''/g, "'");
      } else if (x) {
        foo.splice(x - 1, 2, [foo[x - 1], foo[x]].join(sep));
      } else foo = foo.shift().split(sep).concat(foo);
    } else foo[x].replace(/''/g, "'");
  } return foo;
};

다음과 같이 부를 것입니다.

var string = "'string, duppi, du', 23, lala";
var parsed = string.splitCSV();
alert(parsed.join("|"));

이 jsfiddle 종류의 작동하지만 일부 요소 앞에 공백이있는 것처럼 보입니다.


ridgerunner의 우수하고 완전한 답변 외에도 백엔드가 PHP를 실행할 때 매우 간단한 해결 방법을 생각했습니다.

도메인의 백엔드이 PHP 파일을 추가합니다 (예를 들어 : csv.php)

<?php
session_start(); //optional
header("content-type: text/xml");
header("charset=UTF-8");
//set the delimiter and the End of Line character of your csv content:
echo json_encode(array_map('str_getcsv',str_getcsv($_POST["csv"],"\n")));
?>

이제이 함수를 자바 스크립트 툴킷에 추가하세요 (내가 믿는 크로스 브라우저를 만들기 위해 약간 수정해야합니다).

function csvToArray(csv) {
    var oXhr = new XMLHttpRequest;
    oXhr.addEventListener("readystatechange",
            function () {
                if (this.readyState == 4 && this.status == 200) {
                    console.log(this.responseText);
                    console.log(JSON.parse(this.responseText));
                }
            }
    );
    oXhr.open("POST","path/to/csv.php",true);
    oXhr.setRequestHeader("Content-type","application/x-www-form-urlencoded; charset=utf-8");
    oXhr.send("csv=" + encodeURIComponent(csv));
}

ajax 호출 한 번의 비용이 들지만 적어도 코드를 복제하거나 외부 라이브러리를 포함하지 않습니다.

참고 : http://php.net/manual/en/function.str-getcsv.php


다음 예제와 같이 papaparse.js 를 사용할 수 있습니다 .

<!DOCTYPE html>
<html lang="en">
<head>
    <title>CSV</title>
</head>
<body>

    <input type="file" id="files" multiple="">
    <button onclick="csvGetter()">CSV Getter</button>
    <h3>The Result will be in the Console.</h3>


<script src="papaparse.min.js"></script>
<script>
     function csvGetter() {

        var file = document.getElementById('files').files[0];
        Papa.parse(file, {
            complete: function(results) {
                console.log(results.data);
                }
           });
        }

  </script>

같은 폴더에 papaparse.js를 포함하는 것을 잊지 마십시오.


no regexp, readable, according to https://en.wikipedia.org/wiki/Comma-separated_values#Basic_rules

function csv2arr(str: string) {
    let line = ["",];
    const ret = [line,];
    let quote = false;

    for (let i = 0; i < str.length; i++) {
        const cur = str[i];
        const next = str[i + 1];

        if (!quote) {
            const cellIsEmpty = line[line.length - 1].length === 0;
            if (cur === '"' && cellIsEmpty) quote = true;
            else if (cur === ",") line.push("");
            else if (cur === "\r" && next === "\n") { line = ["",]; ret.push(line); i++; }
            else if (cur === "\n" || cur === "\r") { line = ["",]; ret.push(line); }
            else line[line.length - 1] += cur;
        } else {
            if (cur === '"' && next === '"') { line[line.length - 1] += cur; i++; }
            else if (cur === '"') quote = false;
            else line[line.length - 1] += cur;
        }
    }
    return ret;
}

참고URL : https://stackoverflow.com/questions/8493195/how-can-i-parse-a-csv-string-with-javascript-which-contains-comma-in-data

반응형