У меня есть следующий тип строки

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

Я хочу разбить строку на массив в каждой запятой, но только запятые вне одинарных кавычек.

, который реализует механизм внедрения зависимостей для работы без Angular. Я также обновил

string.split(/,/)

даст мне

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

, но результат должен быть следующим:

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

, есть ли кросс-браузерное решение?

Отказ от ответственности

2014-12-01 Обновление: ответ ниже работает только для одного очень специфического формата CSV. Как правильно указал Д.Г. в комментариях, это решение НЕ соответствует определению CSV в RFC 4180, а также НЕ подходит для формата MS Excel. Это решение просто демонстрирует, как можно проанализировать одну (нестандартную) строку ввода CSV, которая содержит смесь типов строк, где строки могут содержать экранированные кавычки и запятые.

Нестандартное CSV-решение

Как правильно указывает austincheney, вам действительно нужно анализировать строку от начала до конца, если вы хотите правильно обрабатывать строки в кавычках, которые могут содержать экранированные символы. Кроме того, OP не дает четкого определения, что такое «строка CSV». Сначала мы должны определить, что составляет действительную строку CSV и ее отдельные значения.

Дано: Определение «CSV String»

Невозможно динамически изменить значение поля файла, в противном случае вы можете установить его в «c: yourfile» и очень легко красть файлы.

  1. Строка в двойных кавычках. (может содержать неэкранированные одинарные кавычки.)
  2. Строка в одинарных кавычках. (может содержать неэкранированные двойные кавычки.)
  3. Строка без кавычек. (НЕ МОЖЕТ содержать кавычек, запятых или обратной косой черты.)
  4. Пустое значение. (Все пробельные значения считаются пустыми.)

Правила / Примечания:

  • Кавычки могут содержать запятые.
  • Значения в кавычках могут содержать escape-что-нибудь, например, 'that's cool' Глядя на вывод
  • Значения, содержащие кавычки, запятые или обратную косую черту, должны быть заключены в кавычки.
  • Значения, содержащие начальные или конечные пробелы, должны быть заключены в кавычки.
  • Обратная косая черта удаляется из всех: ' в одинарных кавычках.
  • Обратная косая черта удаляется из всех: " в двойных кавычках.
  • Строки без кавычек обрезаются на любые начальные и конечные пробелы.
  • Разделитель запятых может иметь соседний пробел (который игнорируется).

Find:

Функция JavaScript, которая преобразует допустимую строку CSV (как определено выше) в массив строковых значений.

Решение:

Регулярные выражения, используемые этим решением, являются сложными. И (IMHO) все нетривиальные регулярные выражения должны быть представлены в свободном интервале с большим количеством комментариев и отступов. К сожалению, JavaScript не поддерживает режим свободного пробела. Таким образом, регулярные выражения, реализованные этим решением, сначала представляются в собственном синтаксисе регулярных выражений (выражается с помощью удобного в Python синтаксиса: r'''...''' raw-multi-line-string).

Сначала приведем регулярное выражение, которое проверяет, соответствует ли строка CVS указанным выше требованиям:

Regex для проверки «строки 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.
  '[^'\]*(?:\[Ss][^'\]*)*'     # Either Single quoted string,
| "[^"\]*(?:\[Ss][^"\]*)*"     # 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.
    '[^'\]*(?:\[Ss][^'\]*)*'   # Either Single quoted string,
  | "[^"\]*(?:\[Ss][^"\]*)*"   # 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. Он применяется повторно до тех пор, пока больше не будет найдено совпадений (и все значения были проанализированы).

Комбинируя это с решениями IE8 и Webkit, которые также были однострочными, я смог обнаружить масштаб в подавляющем большинстве браузеров, попавших в наше приложение с помощью всего лишь нескольких строк кода.

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.
  '([^'\]*(?:\[Ss][^'\]*)*)'   # Either $1: Single quoted string,
| "([^"\]*(?:\[Ss][^"\]*)*)"   # 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.
"""

Обратите внимание, что есть одно специальное значение, которое не соответствует этому регулярному выражению — самое последнее значение, когда это значение пустое. Этот специальный случай Как получить полный объект при отладке с помощью console.log ()? & # xA ; & {** **} xA ; const myObject = {& # xA ; & quot ; a & quot ; : & quot ; a & quot ;, & # xA ; & quot ; b & quot ;: {& # xA ; & quot ; c & quot ;: & quot ; c & quot ;, & # xA ; & quot ; d { *.} quot ;: {& # xA ; & quot ; e & quot ;: { *.} quot ; e & quot ;, & # xA ; & quot ; f & quot ;: {& # xA ; & quot ; g & quot ;: & quot ; g & quot ;, & # xA ; … вернет проверяется и обрабатывается следующей функцией js.

JavaScript-функция для анализа строки CSV:

// Return array of string values, or NULL if CSV string not well formed.
function CSVtoArray(text) {
    var re_valid = /^s*(?:'[^'\]*(?:\[Ss][^'\]*)*'|"[^"\]*(?:\[Ss][^"\]*)*"|[^,'"s\]*(?:s [^,'"s\] )*)s*(?:,s*(?:'[^'\]*(?:\[Ss][^'\]*)*'|"[^"\]*(?:\[Ss][^"\]*)*"|[^,'"s\]*(?:s [^,'"s\] )*)s*)*$/;
    var re_value = /(?!s*$)s*(?:'([^'\]*(?:\[Ss][^'\]*)*)'|"([^"\]*(?:\[Ss][^"\]*)*)"|([^,'"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}. (Это помогает визуализировать начальные / конечные пробелы и строки нулевой длины.)

// 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 ;, допустимая кодировка — экранирование двойной кавычки с двойной кавычкой. Приведенное ниже решение правильно работает с CSV-файлами d / l из электронных таблиц Google.

ОБНОВЛЕНИЕ (3/2017)

Анализ одной строки был бы неправильным. Согласно 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 CRLFrn"rn"2nd line one","two with escaped """" double quotes""","three, with, commas",four with no quotes,"five with CRLFrn"';
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);

PEG (.js) грамматика, которая обрабатывает примеры RFC 4180 на http://en.wikipedia.org/wiki/Comma- separa_values ​​:

start
  = [nr]* first:line rest:([nr]  data:line { return data; })* [nr]* { 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:[^nr,]* { return text.join(''); }

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

Тест на http://jsfiddle.net/knvzk/10 или https://pegjs.org/online Глядя на вывод

Скачать сгенерированный парсер на https://gist.github.com/3362830 Глядя на вывод

У меня был очень специфический случай использования, когда я хотел скопировать ячейки из Google Sheets в мое веб-приложение. Ячейки могут включать двойные кавычки и символы новой строки. С помощью копирования и вставки ячейки разделяются символами табуляции, а ячейки с нечетными данными заключаются в двойные кавычки. Я попробовал это основное решение, связанную статью, используя regexp, Jquery-CSV и CSVToArray. http://papaparse.com/ Это единственный, который работал из коробки. Скопируйте и вставьте без проблем с Google Sheets с опциями автоматического определения по умолчанию.

Мне понравился ответ 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('|'));

Если вы можете использовать разделитель цитат в двойных кавычках, то это дубликат кода JavaScript для анализа данных CSV Глядя на вывод

Вы можете либо сначала переведите все одинарные кавычки в двойные кавычки:

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.";

В этом случае вы абсолютно не представляете, где начинается или заканчивается подстрока, просто анализируя ввод для шаблона символа. Вместо этого вы должны написать логику, чтобы принять решение о том, используется ли символ кавычки как символ кавычки, сам по себе не заключен в кавычки, и что символ кавычки не следует за escape.

Я не собираюсь писать для вас этот уровень сложности кода, но вы можете посмотреть на то, что я недавно написал, и в котором есть шаблон, который вам нужен. Этот код не имеет ничего общего с запятыми, но в остальном он является достаточно допустимым микропарсером, чтобы вы могли следовать при написании собственного кода. Посмотрите на функцию asifix следующего приложения:

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

Казалось, что люди против RegEx за это. Зачем?

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

Вот код Я также сделал fiddle Глядя на вывод

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 в строку, он содержит нулевое значение между строками, поэтому попробуйте 0 Строка за строкой, это работает мне.

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

Для дополнения . Он включает интерфейс на основе Java, который определяет URL-адреса и упрощает доступ к ним.

Если вам нужно разобрать кавычки, не содержащие другую кавычку, например:

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

Вы можете использовать

function parse(text) {
  const csvExp = /(?!s*$)s*(?:'([^'\]*(?:\[Ss][^'\]*)*)'|"([^"\]*(?:\[Ss][^"\]*)*)"|"([^""]*(?:"[Ss][^""]*)*)"|([^,'"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. Файл содержит столбец Address, который содержит ‘,’.
После анализа этого CSV в JSON я получаю несоответствующее отображение ключей при преобразовании его в файл JSON.
Я использовал узел для разбора файла и библиотеку, как baby parse и csvtojson
Пример файла —

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
}]

Добавление еще одного в список, потому что я считаю, что все вышеперечисленное не совсем достаточно «ПОЦЕЛУЙ».

Этот метод использует регулярные выражения, чтобы найти запятые или символы новой строки, пропуская цитируемые элементы. Надеюсь, это то, что новички могут прочитать самостоятельно. splitFinder Регулярное выражение имеет три вещи, которые оно делает (разделяется на |):

  1. , — находит запятые
  2. r?n — находит новые строки, (потенциально с возвратом каретки, если экспортер был хорош)
  3. "(\"|[^"]) ?" — пропускает все, что заключено в кавычки, потому что запятые и переводы строк здесь не имеют значения. Если в цитируемом элементе есть экранированная кавычка \", она будет захвачена до того, как будет найдена конечная кавычка.
const splitFinder = /,|r?n|"(\"|[^"]) ?"/g;

function csvTo2dArray(parseMe) {
	let currentRow = [];
	const rowsOut = [currentRow];

	let lastIndex = splitFinder.lastIndex = 0;
	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
		if (split.startsWith(`"`) === false) {
			const splitStartIndex = splitFinder.lastIndex - split.length;
			const addMe = parseMe.substring(lastIndex, splitStartIndex);
			// remove quotes around the item
			currentRow.push(addMe.replace(/^"|"$/g, ""));
			lastIndex = splitFinder.lastIndex;

			// 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), removing quotes
	currentRow.push(parseMe.slice(lastIndex).replace(/^"|"$/g, ""));
	return rowsOut;
}

const rawCsv = `a,b,cn"testrn","comma, test","rn",",",nsecond,row,ends,with,emptyn"quote"test"`
const rows = csvTo2dArray(rawCsv);
console.log(rows);

Согласно этого сообщения в блоге , эта функция должна это делать :

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("|"));

this jsfiddle вид работ, но похоже, что у некоторых элементов есть пробелы перед ними.

Помимо отличного и полного ответа от Ridgerunner, я подумал об очень простом Обходной путь для того, когда ваш бэкэнд запускает 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")));
?>

Теперь добавьте эту функцию в ваш инструментарий javascript (нужно немного пересмотреть, чтобы сделать кроссбраузер, я считаю.)

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));
}

Это будет стоить вам 1 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 в ту же папку.