【问题标题】:How to select a value from a comma delimited string?如何从逗号分隔的字符串中选择一个值?
【发布时间】:2013-02-01 16:50:31
【问题描述】:

我有一个包含逗号分隔文本的字符串。逗号分隔的文本来自一个 excel .csv 文件,因此有数百行七列宽的数据。此文件中的一行示例如下:

2012-10-01,759.05,765,756.21,761.78,3168000,761.78

我想按第一列中的日期搜索数百行。一旦找到正确的行,我想提取逗号分隔字符串的第一个位置的数字,所以在这种情况下,我想提取数字 759.05 并将其分配给变量“Open”。

到目前为止我的代码是:

strURL = "http://ichart.yahoo.com/table.csv?s=" & tickerValue
strBuffer = RequestWebData(strURL)

Dim Year As String = 2012
Dim Quarter As String = Q4
If Quarter = "Q4" Then
    Dim Open As Integer =
End If

一旦我可以将其缩小到正确的行,我认为像 row.Split(",")(1).Trim) 这样的东西可能会起作用。

我已经做了很多研究,但我自己无法解决这个问题。有什么建议么!?!

附加信息:

Private Function RequestWebData(ByVal pstrURL As String) As String
    Dim objWReq As WebRequest
    Dim objWResp As WebResponse
    Dim strBuffer As String
    'Contact the website
    objWReq = HttpWebRequest.Create(pstrURL)
    objWResp = objWReq.GetResponse()
    'Read the answer from the Web site and store it into a stream
    Dim objSR As StreamReader
    objSR = New StreamReader(objWResp.GetResponseStream)
    strBuffer = objSR.ReadToEnd
    objSR.Close()

    objWResp.Close()

    Return strBuffer
End Function 

更多信息:

我的代码更完整的图片

Dim tickerArray() As String = {"GOOG", "V", "AAPL", "BBBY", "AMZN"}

For Each tickerValue In Form1.tickerArray

        Dim strURL As String
        Dim strBuffer As String
        'Creates the request URL for Yahoo
        strURL = "http://ichart.yahoo.com/table.csv?s=" & tickerValue

        strBuffer = RequestWebData(strURL)

        'Create Array
        Dim lines As Array = strBuffer.Split(New String() {Environment.NewLine}, StringSplitOptions.None)

        'Add Rows to DataTable
        dr = dt.NewRow()
        dr("Ticker") = tickerValue
        For Each columnQuarter As DataColumn In dt.Columns
            Dim s As String = columnQuarter.ColumnName
            If s.Contains("-") Then
                Dim words As String() = s.Split("-")
                Dim Year As String = words(0)
                Dim Quarter As String = words(1)
                Dim MyValue As String
                Dim Open As Integer
                If Quarter = "Q1" Then MyValue = Year & "-01-01"
                If Quarter = "Q2" Then MyValue = Year & "-04-01"
                If Quarter = "Q3" Then MyValue = Year & "-07-01"
                If Quarter = "Q4" Then MyValue = Year & "-10-01"
                For Each line In lines
                    Debug.WriteLine(line)
                    If line.Split(",")(0).Trim = MyValue Then Open = line.Split(",")(1).Trim
                    dr(columnQuarter) = Open
                Next
            End If

        Next
        dt.Rows.Add(dr)
    Next

现在在For Each line in lines 循环中,Debug.WriteLine(line) 输出 2,131 行:

来自

Date,Open,High,Low,Close,Volume,Adj Close
2013-02-05,761.13,771.11,759.47,765.74,1870700,765.74
2013-02-04,767.69,770.47,758.27,759.02,3040500,759.02
2013-02-01,758.20,776.60,758.10,775.60,3746100,775.60

一路...

2004-08-19,100.00,104.06,95.96,100.34,22351900,100.34

但是,我期望Debug.WriteLine(line)For Each line in lines 循环中一次输出一行。所以我希望第一个输出是Date,Open,High,Low,Close,Volume,Adj Close,下一个输出是2013-02-05,761.13,771.11,759.47,765.74,1870700,765.74。我预计这会发生 2,131 次,直到最后一个输出是 2004-08-19,100.00,104.06,95.96,100.34,22351900,100.34

【问题讨论】:

  • 我实际上更改了帖子的这些值,以便我可以发布我的代码的缩写版本。这些值实际上是从代码前面的字符串中拆分出来的。它们看起来像 Dim Year As String = words(0) Dim Quarter As String = words(1)
  • @TimSchmelter “尽快将您的 OPTION STRICT 更改为“ON”!”是什么意思?

标签: vb.net csv string-split


【解决方案1】:

您可以遍历这些行并调用String.Split 来解析每一行中的列,例如:

Dim lines() As String = strBuffer.Split(New String() {Environment.NewLine}, StringSplitOptions.None)
For Each line As String In lines
    Dim columns() As String = line.Split(","c)
    Dim Year As String = columns(0)
    Dim Quarter As String = columns(1)
Next

但是,有时 CSV 并不是那么简单。例如,电子表格中的单元格可能包含逗号字符,在这种情况下,它将在 CSV 中表示如下:

example cell 1,"example, with comma",example cell 3

为确保您正确处理所有可能性,我建议使用 TextFieldParser 类。例如:

Using parser As New TextFieldParser(New StringReader(strBuffer))
    parser.TextFieldType = FieldType.Delimited
    parser.SetDelimiters(",")
    While Not parser.EndOfData
        Try
            Dim columns As String() = parser.ReadFields()
            Dim Year As String = columns(0)
            Dim Quarter As String = columns(1)
        Catch ex As MalformedLineException
            ' Handle the invalid formatting error
        End Try 
    End While 
End Using

【讨论】:

  • 当我使用此方法然后使用 Debug.WriteLine(lines) 进行调试时,它告诉我“lines”返回“System.String[]”,我希望看到该数组。
  • String[] 是一个字符串数组。这就是[] 的意思。
  • 啊。你的意思是 String.Split 只返回一项?在这种情况下,最可能的罪魁祸首是 CSV 文件中使用的换行符与 Environment.NewLine 不同。
  • 您可以使用任何二进制文本编辑器查看字符的十六进制代码。很可能是ControlChars.CrControlChars.Lf。不过,如果您使用的是TextFieldParser 类,这也不是问题。或者,您可以使用StringReader 对象并在循环中调用它的ReadLine 方法。 StringReader.ReadLine 方法支持所有标准的换行符。
  • 你的意思是我建议你在哪里可以使用StringReader 类? StringReaderStreamReader 不同。
【解决方案2】:

我会将其分解为 List(of string()) - 每行都是列表中的一个新条目。

然后循环遍历列表并查看 Value(0)。 If Value(0) = MyValue, then Open = Value(1)

【讨论】:

  • 听起来不错!是什么将其分解为 List(of string())?
  • 你在哪里读取数据??如果您正在逐行阅读它,那么只需在每一行中使用MyList.Add 方法将其加载到列表中。如果您已经将它作为一个长字符串使用,例如 VBCrLf 分隔每一行的字符,那么只需将其拆分为该字符并使用 .ToList 方法
  • ...如果您显示您在数据中的读取位置/方式,我们将能够提供更多帮助。
  • 我编辑了我的原始帖子以显示我在哪里/如何读取数据。
  • 在我的回答中,您可以使用strBuffer.Split(New String() {Environment.NewLine}, StringSplitOptions.None) 来获取行数组,或者您可以创建一个New StringReader(strBuffer),然后在循环中继续调用StringReader.ReadLine
【解决方案3】:

您可以使用String.Split 和这个 linq 查询:

Dim Year As Int32 = 2012
Dim Month As Int32 = 10
Dim searchMonth = New Date(Year, Month, 1)
Dim lines = strBuffer.Split({Environment.NewLine}, StringSplitOptions.None)
Dim dt As Date
Dim open As Double
Dim opens = From line In lines
    Let tokens = line.Split({","c}, StringSplitOptions.RemoveEmptyEntries)
    Where Date.TryParse(tokens(0), dt) AndAlso dt.Date = searchMonth AndAlso Double.TryParse(tokens(1), open)
If opens.Any() Then
    open = Double.Parse(opens.First().tokens(1))
End If

【讨论】:

    猜你喜欢
    • 2020-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 2017-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多