2016-06-09 3 views
0

Я использую NodeJS для потока CSV-файла и должен обрабатывать каждую строку. Я не нашел узел parser csv узла, который поддерживает символы новой строки в двойных кавычках должным образом.Узел regex для соответствия символу новой строки, но не новой строки между кавычками

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

Что-то вроде /(\r?\n)/ находит новые строки, но как я могу опустить новую строку в строки с двумя кавычками?

пример ввода (обратите внимание на строку во второй строке):

1,2,3,"foo bar baz",4,5 
2,2,3,"foo bar 
baz",4,5 
3,2,3,"foo bar baz",4,5 
inputCsvStream.pipe(split(/regex-for-newline-not-in-quotes/)).on('data', (line) => { 
    // do something with proper csv line 
}); 

Спасибо!

ответ

1

Вместо split, вы можете использовать CSV Parse пакет, с которым вы могли бы написать:

var parse = require('csv-parse'); 
//... 
inputCsvStream.pipe(parse).on('data', (line) => { 
    // do something with proper csv line 
}); 

Если вы действительно хотите придерживаться split для этого p ЗАДАЧА, вы можете использовать эту функцию, когда вы включаете в результатах расщепленной часть разделителя, который находится в улавливающих группы:

inputCsvStream.pipe(split(/(.*?(?:"[^"]*"*.*?)*)\r?\n/)).on('data', (line) => { 
    // ignore the empty lines between the "delimiters" 
    if (!line.length) return; 
    // do something with proper csv line 
}); 

Это займет часть между наружными скобками (в регулярном выражении) и добавить его к результату трубопровода. Очевидно, splitтакже соединяет части между разделителями, которые в этом случае всегда пустыми. Поэтому они должны быть явно устранены после расщепления.

+0

Спасибо за мысли. Я попробовал 'csv-parse'. К сожалению, похоже, что он неправильно обрабатывает символы новой строки в двойных кавычках. Он разбивает линию на них. Если у меня не хватает некоторых настроек или параметров. –

-1

Вы могли бы поставить отрицательное опережения утверждение в конце:

(\r?\n)(?![^",]*")

Regex demo

+1

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

0

По крайней мере fast-csv поддерживает это:

const csv = require('fast-csv'); 

csv.fromString(`\ 
1,2,3,"foo bar baz",4,5 
2,2,3,"foo bar 
baz",4,5 
3,2,3,"foo bar baz",4,5 
`).on('data', (d) => { 
    console.log(d); 
}); 

Выход:

[ '1', '2', '3', 'foo bar baz', '4', '5' ] 
[ '2', '2', '3', 'foo bar \nbaz', '4', '5' ] 
[ '3', '2', '3', 'foo bar baz', '4', '5' ] 
+0

Я пробовал 'fast-csv', но это было намного медленнее, чем альтернативы, и он, похоже, не поддерживал фактические новые строки в строке (я знаю, что typing \ n в строке работает нормально), по крайней мере в моих тестах , –

+0

Код в примере _contains_ фактическая строка новой строки в строке. Если вы этого не верите, используйте 'csv.fromPath ('your-file.csv')' вместо 'csv.fromString()'. Я получил довольно приличные результаты от него, разобрав записи 40K менее чем за полсекунды. – robertklep

+0

Интересно, я просто попробовал еще раз, и у меня все еще такая же проблема. Обработайте поток, трубу через fast-csv, он по-прежнему рассматривает это как новую строку. –