【发布时间】:2014-12-12 18:46:42
【问题描述】:
网络上有很多搜索结果(以及在 SO 中)与我需要做的事情相似,但我还没有找到适合我的特殊情况的解决方案。
我有一个逗号分隔的文件,其中只有包含逗号的列在它们周围有双引号。其他没有逗号的字段用逗号简单分隔。
举个例子:
123,"box,toy",phone,"red,car,cat,dog","bike,pencil",man,africa,yellow,"jump,rope"
该行的输出需要是:
123|box,toy|phone|red,car,cat,dog|bike,pencil|man|africa|yellow|jump,rope
我目前有这个代码:
Using sr As New StreamReader(csvFilePath)
Dim line As String = ""
Dim strReplacerQuoteCommaQuote As String = Chr(34) & "," & Chr(34)
Dim strReplacerQuoteComma As String = Chr(34) & ","
Dim strReplacerCommaQuote As String = "," & Chr(34)
Do While sr.Peek <> -1
line = sr.ReadLine
line = Replace(line, strReplacerQuoteCommaQuote, "|")
line = Replace(line, strReplacerQuoteComma, "|")
line = Replace(line, strReplacerCommaQuote, "|")
line = Replace(line, Chr(34), "")
Console.WriteLine("line: " & line)
Loop
End Using
这个过程的问题是当我到达第四个 Replace() 行时,字符串看起来像这样:
123|box,toy|phone|red,car,cat,dog|bike,pencil|man,africa,yellow|jump,rope
所以 man 和 africa 需要在它们之后使用管道,但显然我不能只对所有逗号进行替换。
我该怎么做?有没有可以处理这个问题的 RegEx 语句?
使用工作代码更新
Avinash 评论中的link 给出了我所接受的答案。我导入了 System.Text.RegularExpressions 并使用了以下内容:
Using sr As New StreamReader(csvFilePath)
Dim line As String = ""
Dim strReplacerQuoteCommaQuote As String = Chr(34) & "," & Chr(34)
Dim strReplacerQuoteComma As String = Chr(34) & ","
Dim strReplacerCommaQuote As String = "," & Chr(34)
Do While sr.Peek <> -1
line = sr.ReadLine
Dim pattern As String = "(,)(?=(?:[^""]|""[^""]*"")*$)"
Dim replacement As String = "|"
Dim regEx As New Regex(pattern)
Dim newLine As String = regEx.Replace(line, replacement)
newLine = newLine.Replace(Chr(34), "")
Console.WriteLine("newLine: " & newLine)
Loop
End Using
【问题讨论】:
-
我认为最好使用 csv 文件解析器。如果您想使用正则表达式,那么这个 answer 将帮助您匹配出现在双引号之外的所有逗号。最后将所有匹配的逗号替换为
| -
在未来,我会远离任何像
"(,)(?=(?:[^""]|""[^""]*"")*$)"这样的正则表达式,因为它每次匹配逗号时都必须向前看字符串的末尾,比如 n 阶乘。 -
果然:我目前正在测试最终用户将转换的完整“生产”版本文件。它有大约 90k 行,并且需要花费 LOOOOOOOOONG 时间来转换!对此还有什么其他的攻击角度?
-
听起来您还有其他问题。我刚刚在不到 2 秒的时间内处理了一个包含 90k 行
123,"box,toy",phone,"red,car,cat,dog","bike,pencil",man,africa,yellow,"jump,rope"的文本文件。您实际上对提取的数据做了什么? -
@Blue Dog 有趣的是,您的处理速度如此之快。我使用的实际文件有 14 个字段,每行最多一到两个字段中大约 200 个字符,但我认为这不会有太大的不同。我将不得不设置一个仅使用转换代码的测试应用程序,看看我是否可以追踪可能减慢它的任何东西。不过,感谢您对此进行检查。
标签: regex vb.net csv replace substring