/
str_getcsv.js
57 lines (46 loc) · 2.03 KB
/
str_getcsv.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
module.exports = function str_getcsv(input, delimiter, enclosure, escape) {
// discuss at: https://locutus.io/php/str_getcsv/
// original by: Brett Zamir (https://brett-zamir.me)
// example 1: str_getcsv('"abc","def","ghi"')
// returns 1: ['abc', 'def', 'ghi']
// example 2: str_getcsv('"row2""cell1","row2cell2","row2cell3"', null, null, '"')
// returns 2: ['row2"cell1', 'row2cell2', 'row2cell3']
/*
// These test cases allowing for missing delimiters are not currently supported
str_getcsv('"row2""cell1",row2cell2,row2cell3', null, null, '"');
['row2"cell1', 'row2cell2', 'row2cell3']
str_getcsv('row1cell1,"row1,cell2",row1cell3', null, null, '"');
['row1cell1', 'row1,cell2', 'row1cell3']
str_getcsv('"row2""cell1",row2cell2,"row2""""cell3"');
['row2"cell1', 'row2cell2', 'row2""cell3']
str_getcsv('row1cell1,"row1,cell2","row1"",""cell3"', null, null, '"');
['row1cell1', 'row1,cell2', 'row1","cell3'];
Should also test newlines within
*/
let i
let inpLen
const output = []
const _backwards = function (str) {
// We need to go backwards to simulate negative look-behind (don't split on
// an escaped enclosure even if followed by the delimiter and another enclosure mark)
return str.split('').reverse().join('')
}
const _pq = function (str) {
// preg_quote()
return String(str).replace(/([\\.+*?[^\]$(){}=!<>|:])/g, '\\$1')
}
delimiter = delimiter || ','
enclosure = enclosure || '"'
escape = escape || '\\'
const pqEnc = _pq(enclosure)
const pqEsc = _pq(escape)
input = input.replace(new RegExp('^\\s*' + pqEnc), '').replace(new RegExp(pqEnc + '\\s*$'), '')
// PHP behavior may differ by including whitespace even outside of the enclosure
input = _backwards(input)
.split(new RegExp(pqEnc + '\\s*' + _pq(delimiter) + '\\s*' + pqEnc + '(?!' + pqEsc + ')', 'g'))
.reverse()
for (i = 0, inpLen = input.length; i < inpLen; i++) {
output.push(_backwards(input[i]).replace(new RegExp(pqEsc + pqEnc, 'g'), enclosure))
}
return output
}