我收到了一个带有有趣CSV格式的大文件来解析数据库。
分隔符是分号(;
)。如果其中一个字段包含分号,则通过将其包装在双引号中进行“转义”,例如";"
。
我确信永远不会有两个相邻的字段带有尾随/前导双引号,所以这种格式在技术上应该没问题。
现在,为了在VBScript中解析它,我想到了
";"
的每个实例";"
这似乎是最快捷的方式。有没有更好的办法?我想我可以使用子串,但这种方法似乎是可以接受的......
答案 0 :(得分:2)
您的方法听起来不错,但需要注意的是,您的GUID在文本本身中绝对存在 no 的可能性。
我之前用过这种类型的数据的方法就是分裂在分号上,不管怎样,如果两个相邻的字段结束并以引号开头,则将它们组合起来。
例如:
Pax;is;a;good;guy";" so;says;his;wife.
变为:
0 Pax
1 is
2 a
3 good
4 guy"
5 " so
6 says
7 his
8 wife.
然后,当您发现字段4和5结束并分别以引号开始时,您可以通过用分号替换字段4结束引号并删除字段5开头引用(当然加入它们)来组合它们
0 Pax
1 is
2 a
3 good
4 guy; so
5 says
6 his
7 wife.
答案 1 :(得分:1)
在伪代码中,给出:
input :一个字符串,第一个字符是 input [0];持续
字符是输入 [长度]。此外,假设一个假人
字符,输入 [长度 +1]。它可以是任何东西,除了
;
和"
。该字符串是“CSV”文件的一行。
长度:正整数,输入中的字符数
这样做:
设置开始 = 0
如果输入 [0] = ';'
:
你开头有一个空白字段;用它做任何事情
设置开始= 2
ENDIF
每个 c 介于1和之间:
下一次迭代,除非 string [ c ] = ';'
如果输入[c-1]≠'"'
或输入[c + 1]≠'"'
: //测试转义序列";"
找到半开范围的字段常量[start,c);做任何事 用它。注意,在空字段的情况下,start≥c,离开 一个空的范围
设置start = c + 1
ENDIF
结束foreach
当然没有经过测试。像这样调试代码总是很有趣......
input [0]的特殊情况是确保我们不会查看 input [-1] 。如果您可以安全地输入输入[-1] ,那么您可以摆脱这种特殊情况。您还可以在 input [0]中放置一个虚拟字符,然后从输入 [1]开始您的数据和解析。
答案 2 :(得分:1)
一种选择是查找正则表达式的实例:
[^"];[^"]
然后用子串打破字符串:
List<string> ret = new List<string>();
Regex r = new Regex(@"[^""];[^""]");
Match m;
while((m = r.Match(line)).Success)
{
ret.Add(line.Substring(0,m.Index + 1);
line = line.Substring(m.Index + 2);
}
(抱歉C#,我不知道VBScript)
答案 3 :(得分:0)
对.csv文件使用引号是正常的。如果您在该字段中有引号,那么您可能会看到打开和关闭以及嵌入的引用连续两行或三连在一起。
答案 4 :(得分:0)
如果您使用的是SQL Server,可以尝试使用T-SQL为您处理所有事情。
SELECT * INTO MyTable FROM OPENDATASOURCE('Microsoft.JET.OLEDB.4.0', 'Data Source=F:\MyDirectory;Extended Properties="text;HDR=No"')... [MyCsvFile#csv]
这将创建并填充“MyTable”。在SO上了解有关此主题here的更多信息。
答案 5 :(得分:0)
我建议使用RegEx来分解字符串。
现在您的字段包含正确的数据。
大多数进口商可以非常轻松地换出分隔符。
这基本上是你的GUID想法。在开始之前,只需确保GUID对您的文件是唯一的,您就可以了。我倾向于开始使用'Z'。经过足够的'Z'之后,你将是独一无二的(有时只有少数人会做到这一点)。
雅各