Как я могу проанализировать строку CSV с Javascript, который содержит запятую в данных? - PullRequest
78 голосов
/ 13 декабря 2011

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

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

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

Не могувыяснить правильное регулярное выражение для разделения ...

string.split(/,/)

даст мне

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

но результат должен быть:

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

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

Ответы [ 15 ]

1 голос
/ 14 декабря 2011

Люди, кажется, были против 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('|'));
1 голос
/ 13 декабря 2011

Мой ответ предполагает, что ваш ввод является отражением кода / контента из веб-источников, в которых одинарные и двойные кавычки полностью взаимозаменяемы при условии, что они встречаются как набор без совпадений.

Вы не можете использовать регулярное выражение для этого,На самом деле вам нужно написать микро-парсер для анализа строки, которую вы хотите разделить.Ради этого ответа я буду называть процитированные части ваших строк как подстроки.Вам нужно специально пройтись по струне.Рассмотрим следующий случай:

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

0 голосов
/ 21 октября 2018

Вы можете использовать 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 в тот жепапка.

0 голосов
/ 26 марта 2015

Помимо отличного и полного ответа от 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")));
?>

Теперь добавьте эту функцию в ваш инструментарий 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

0 голосов
/ 13 декабря 2011

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

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 работает, но похоже, что перед некоторыми элементами есть пробелы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...