Vue处理CSV列名包含逗号问题
该函数的目的是解析 CSV 文件的头部行(即第一行),并提取出所有的列名。CSV 文件是一种常用的文本格式,用于存储结构化数据,其中列与列之间通常用逗号分隔。有时,列名或列值中可能包含逗号,这时需要用双引号将整个列名或列值括起来,以确保正确的解析。
工作原理
正则表达式:
/"(?:[^"]|"")*"|,|\r\n|\n|\r/gm
:
"
:匹配双引号,表示一个可能包含逗号的列名的开始或结束。(?:[^"]|"")*
:匹配零个或多个非双引号字符,或者一个双引号字符(如果前一个字符也是双引号,则表示转义的双引号)。"
:匹配双引号,表示一个可能包含逗号的列名的结束。|
:逻辑 “或” 操作符,用于匹配逗号、换行符等。,
:匹配逗号,表示列与列之间的分隔符。\r\n|\n|\r
:匹配行结束符,即回车符、换行符或回车换行符的组合。gm
:g
表示全局匹配,m
表示多行匹配。解析逻辑:
- 初始化一个空数组
matches
来存储解析出的列名。- 初始化一个变量
startIndex
来记录上一个匹配的起始位置。- 使用
while
循环和regex.exec(headerLine)
来逐个匹配列名或分隔符。- 如果当前匹配的起始位置
match.index
大于startIndex
,则表示我们找到了一个新的列名(或列名的一部分)。将这部分内容添加到matches
数组中。- 更新
startIndex
为当前匹配的结束位置,即match.index + match[0].length
。- 循环结束后,检查是否还有剩余的文本未被匹配。如果有,将其作为一个额外的列名添加到
matches
数组中(这种情况可能发生在列名包含换行符时)。- 最后,返回
matches
数组,其中包含了所有的列名。例子
假设
headerLine
是a,"b,c",d
。
- 正则表达式首先匹配到
a
,然后是"
,接着是"b,c"
(其中包含逗号),然后是"
,最后是,
。- 在第一次循环中,
startIndex
是 0,match.index
是 1,所以match.index > startIndex
成立。因此,"a"
被添加到matches
数组中。startIndex
更新为 2(即match.index + match[0].length
)。- 下一次循环匹配到
"
,"b,c"
和"
,但match.index
(此时是 5)不大于startIndex
(此时是 2),所以这部分不被添加到matches
数组中。- 循环继续,匹配到
,
,然后是d
。- 最后,因为
startIndex
(此时是 9)小于headerLine.length
(此时是 10),所以"d"
被添加到matches
数组中。- 函数返回
matches
数组,此时包含["a", "b,c", "d"]
。这样,即使列名中包含逗号或换行符,函数也能正确地将它们解析为单独的列名
代码如下(可以直接调用):
const handleFileChange = (file) => {
if (file && file.raw) {
const reader = new FileReader();
reader.onload = (e) => {
const csvData = e.target.result;
const lines = csvData.split('\n');
if (lines.length > 0) {
const header = parseHeader(lines[0]);
columns.value = header; // 读取所有列名
fileSelected.value = true;
}
};
uploadFile1(file.raw);
reader.readAsText(file.raw);
}
};
const parseHeader = (headerLine) => {
const regex = /"(?:[^"]|"")*"|,|\r\n|\n|\r/gm;
let match;
const matches = [];
let startIndex = 0; // 记录上一个匹配的起始位置
while ((match = regex.exec(headerLine)) !== null) {
// 检查是否是列名的一部分
if (match.index > startIndex) {
// 添加之前匹配的列名
matches.push(headerLine.substring(startIndex, match.index).replace(/""/g, '"'));
}
startIndex = match.index + match[0].length; // 更新下一个匹配的起始位置
}
// 添加最后一列(如果有的话)
if (startIndex < headerLine.length) {
matches.push(headerLine.substring(startIndex).replace(/""/g, '"'));
}
return matches;
};
原文地址:https://blog.csdn.net/m0_64694079/article/details/144797672
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!