我需要读取一个 CSV 文件,而我唯一可以使用的语言是 VBscript。
我目前只是打开文件并用逗号分割,它工作正常,因为字段中没有任何带引号的逗号。但我知道这是一个非常脆弱的解决方案。
那么,有没有我可以使用的 VBscript 模块之类的东西?在某个地方可以获得一个经过验证的正则表达式,它只会在逗号而不是引号中分割?
任何建议都非常感激。
VBScript 没有可与 Perl 相媲美的模块系统。但是,您可以使用ADO打开 CSV 文件并像访问数据库表一样访问它们。代码会是这样的:
(有趣的评论只是为了修复 SO 损坏的 VB 语法突出显示)
Dim conn ''// As ADODB.Connection
Dim rs ''// As ADODB.RecordSet
Dim connStr ''// As String
Dim dataDir ''// As String
dataDir = "C:\" '"
connStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & dataDir & ";Extended Properties=""text"""
Set conn = CreateObject("ADODB.Connection")
conn.Open(connStr)
Set rs = conn.Execute("SELECT * FROM [data.txt]")
''// do something with the recordset
WScript.Echo rs.Fields.Count & " columns found."
WScript.Echo "---"
WScript.Echo rs.Fields("Col1Name").Value
If Not rs.EOF Then
rs.MoveNext
WScript.Echo rs.Fields("Col3Name").Value
End If
''// explicitly closing stuff is somewhat optional
''// in this script, but consider it a good habit
rs.Close
conn.Close
Set rs = Nothing
Set conn = Nothing
创建一个schema.ini
准确描述您的输入的文件是最佳选择。如果你不这样做,你会强迫文本驱动程序猜测,如果它猜错了,所有的赌注都将被取消。schema.ini
必须位于数据所在的同一目录中。
我的看起来像这样:
[data.txt]
Format=Delimited(;)
DecimalSymbol=.
ColNameHeader=True
MaxScanRows=0
Col1=Col1Name Long
Col2=Col2Name Long
Col3=Col3Name Text
Col4=Col4Name Text
有了这个data.txt
:
a;b;c;d
1;2;"foo bar";"yadayada"
1;2;"sample data";"blah"
我得到这个输出:
C:\>cscript -nologo data.vbs
4 columns found.
---
1
sample data
C:\>
在这方面值得一读:MSDN 上关于文本文件的很多 ADO 。
您可以尝试将 Excel ODBC 数据源创建为 CSV(我认为称为 DSN。它在Control Panel -> Administrative Tools -> ODBC Data Sources中。然后,您可以使用 SQL 查询它。
我仍然不确定你是否能得到你想要的。我的意思是插入一个带有逗号的字符串作为特定单元格的值。
一个正则表达式:
'Credits go to http://www.codeguru.com/cpp/cpp/algorithms/strings/article.php/c8153/
r.Pattern = ",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))"
它将找到所有不在引号内的逗号。
或者,您可以使用我刚刚为 vbs 改编的这个函数。
call test
Function ParseCSV(StringToParse, Quotes)
Dim i, r(), QuotedItemStart, prevpos
ReDim r(0)
prevpos = 1
For i = 1 To Len(StringToParse)
If Mid(StringToParse, i, 1) = "," Then
If QuotedItemStart = 0 Then
r(UBound(r)) = Trim(Mid(StringToParse, prevpos, i - prevpos))
ReDim Preserve r(UBound(r) + 1)
prevpos = i + 1
End If
Else
If InStr(1, Quotes, Mid(StringToParse, i, 1)) Then
If QuotedItemStart Then
r(UBound(r)) = Trim(Mid(StringToParse, QuotedItemStart, i - QuotedItemStart))
ReDim Preserve r(UBound(r) + 1)
QuotedItemStart = 0
prevpos = i + 2
i = i + 1
Else
QuotedItemStart = i + 1
End If
End If
End If
Next
If prevpos < Len(StringToParse) Then r(UBound(r)) = Trim(Mid(StringToParse, prevpos))
ParseCSV = r
End Function
Sub Test()
Dim i, s
s = ParseCSV("""This is, some text!"",25,""Holy holes!"", 286", """")
For i = LBound(s) To UBound(s)
msgbox s(i)
Next
msgbox "Items: " & CStr(UBound(s) - LBound(s) + 1)
End Sub