Last active
March 15, 2020 15:06
-
-
Save vace/ff71809794e83693af1ea56263a677f9 to your computer and use it in GitHub Desktop.
csv text parse object
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* [csvTextParser 简单的csv文本解析器] | |
* @param {string} text [csv文本] | |
* @param {boolean} columns [读取第一行做为表头] | |
* @param {array} columns [列配置] | |
* @param {string} columns[i].field 字段名 | |
* @param {int} columns[i].index? 对应列索引,默认为i | |
* @param {int} columns[i].trim? 是否首尾去空 | |
* @param {string|Function} columns[i].type 字段类型(int,float,string,boolean,function) | |
* @param {object} options [解析配置] | |
* @param {string} options.charRow [行分隔符] | |
* @param {string} options.charColon [字段包裹符号] | |
* @param {string} options.charDivide [列分隔符] | |
* @return {[type]} [description] | |
*/ | |
function csvTextParser (text, columns, options = {}) { | |
// 配置 | |
const {charRow = "\n", charColon = '"', charDivide = ',', trim} = options | |
const textCount = text.length | |
let isInColon = false | |
let tempChars = '' | |
let array = [] | |
let row | |
const pushColumn = (column) => { | |
row.push(tempChars) | |
tempChars = '' | |
} | |
const pushRow = () => { | |
row = [] | |
array.push(row) | |
} | |
for (var i = 0; i <= textCount; i++) { | |
let char = text[i] | |
if (isInColon) { // 进入包裹区域 | |
if (char === charColon) { | |
i += 1 | |
let nextChar = text[i] | |
if (nextChar === charDivide || nextChar == null) { | |
isInColon = false | |
pushColumn() | |
continue | |
} else if (nextChar === charRow) { | |
isInColon = false | |
pushColumn() | |
pushRow() | |
continue | |
} | |
} | |
} else { | |
if (char === charDivide) { // 分列 | |
pushColumn() | |
continue | |
} else if (char === charRow) { | |
pushColumn() | |
pushRow() | |
continue | |
} else if (char === charColon) { | |
let prevChar = text[i - 1] | |
if (prevChar === charDivide || prevChar === charRow || prevChar == null) { | |
isInColon = true | |
continue | |
} | |
} | |
} | |
if (i === 0) { | |
pushRow() | |
} else if (i === textCount) { | |
pushColumn() | |
} | |
tempChars += char | |
} | |
let renderType = (value, row, type, col) => { | |
if (!type) return value | |
if (typeof type === 'function') { | |
return type(value, row, col) | |
} | |
switch (type) { | |
case 'int': return parseInt(value, 10) | |
case 'float': return parseFloat(value) | |
case 'string': return String(value) | |
case 'boolean': return !!value | |
case 'json': return JSON.parse(value) | |
default: | |
console.warn('unknow type:', type) | |
return value | |
} | |
} | |
if (!columns) { | |
return array | |
} | |
if (columns === true) { | |
columns = array.shift() | |
} | |
return array.map(cols => { | |
var object = {} | |
columns.forEach((col, _index) => { | |
if (typeof col === 'string') { | |
object[col] = cols[_index] | |
} else { | |
const { field = _index, index = _index, type, trim } = col | |
const value = renderType(cols[index], cols, type, col) | |
object[field] = trim && typeof value === 'string' ? value.trim() : value | |
} | |
}) | |
return object | |
}) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// parse array test | |
console.log(csvTextParser(`1,小明,早上好 | |
2,小张,下午好 | |
3,未知,"很多冒号""道,”””ss’’’""服务中心" | |
4,"换行 | |
测试","冒号测试""呵 | |
呵🙄"`)) | |
// parse simple object | |
console.log(csvTextParser(`1,小明,98.6 | |
2,小张,99.99999`, ['id', 'name', 'score'])) | |
// parse object | |
console.log(csvTextParser(`1,小明,98.6 | |
2,小张,99.99999`, [ | |
{field: 'id', type: 'int'}, | |
{field: 'name', type: 'string'}, | |
{field: 'score', type: 'float'} | |
])) | |
// parse mixed object | |
console.log(csvTextParser(`1,小明,80.5,B | |
2,小张,90.5,A`, [ | |
{field: 'id', type: 'int'}, | |
'name', | |
{field: 'score', type: 'float'}, | |
{field: 'surplus', index: 2, type: value => { | |
return 100 - value | |
}}, | |
{field: 'level', index: 3} | |
])) | |
// parse header | |
console.log(csvTextParser(`ID,name,score,level | |
1,小明,80.5,B | |
2,小张,90.5,A`, true)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment