2

我正在研究解析一个分隔字符串,大约是

a,b,c

但这是一个非常简单的例子,解析分隔数据会变得很复杂;例如

1,“你的简单算法,它失败了”,真

会把你天真的 string.Split 实现吹成碎片。有什么我可以自由使用/窃取/复制和粘贴的东西,可以为解析分隔文本提供相对安全的解决方案吗?.NET,plox。

更新: 我决定使用TextFieldParser,它是隐藏在 Microsoft.VisualBasic.DLL 中的 VB.NET 一堆好东西的一部分。

4

9 回答 9

4

我用它来读取文件

string filename = @textBox1.Text;
string[] fields;
string[] delimiter = new string[] {"|"};
using (Microsoft.VisualBasic.FileIO.TextFieldParser parser =
       new Microsoft.VisualBasic.FileIO.TextFieldParser(filename)) {
    parser.Delimiters = delimiter;
    parser.HasFieldsEnclosedInQuotes = false;

    while (!parser.EndOfData) {
        fields = parser.ReadFields();
        //Do what you need
    }
}

我相信这里有人可以将其转换为解析内存中的字符串。

于 2008-08-13T19:18:26.730 回答
2

我不知道任何框架,但是一个简单的状态机可以工作:

  • 状态 1:读取每个字符,直到您点击 " 或 a ,
    • 如果是“:移动到状态 2
    • 如果是 ,: 移动到状态 3
    • 在文件结束的情况下:移动到状态 4
  • 状态 2:读取每个字符,直到您点击“
    • 如果是 ": 移动到状态 1
    • 在文件结束的情况下:移动到状态 4 或由于未终止的字符串而发出错误信号
  • 状态 3:将当前缓冲区添加到输出数组,将光标向前移动到 后面,然后回到状态 1。
  • 状态 4:这是最终状态,除了返回输出数组之外什么都不做。
于 2008-08-13T18:53:44.660 回答
2

var elements = new List<string>();
var current = new StringBuilder();
var p = 0;

while (p < internalLine.Length) {
    if (internalLine[p] == '"') {
        p++;

        while (internalLine[p] != '"') {
            current.Append(internalLine[p]);
            p++;
        }

        // Skip past last ',
        p += 2;
    }
    else {
        while ((p < internalLine.Length) && (internalLine[p] != ',')) {
            current.Append(internalLine[p]);
            p++;
        }

        // Skip past ,
        p++;
    }

    elements.Add(current.ToString());
    current.Length = 0;
}
于 2008-08-13T18:57:15.463 回答
2

可以在这里找到一个非常全面的库:FileHelpers

于 2008-11-05T17:04:01.933 回答
1

这里有一些很好的答案:Split a string ignoring quoted section

您可能想将您的问题重新表述为更精确的内容(例如,我可以使用哪些代码片段或库来解析 .NET 中的 CSV 数据?)。

于 2008-08-13T18:55:40.427 回答
1

为了做一个无耻的插件,我一直在研究一个名为fotelo (格式化文本加载器)的库,我用它来快速解析基于分隔符、位置或正则表达式的大量文本。对于快速字符串来说,它是矫枉过正的,但如果您正在使用日志或大量,它可能正是您所需要的。它使用类似于 SQL*Loader 的控制文件模型(它背后的灵感)。

于 2008-08-13T19:54:40.807 回答
1

迟到总比没有好(增加 SO 的完整性):

http://www.codeproject.com/KB/database/CsvReader.aspx

这是一项规则。

GJ

于 2011-06-30T11:02:55.473 回答
0

我认为通用框架需要在两件事之间指定:1.什么是分隔符。2. 在什么情况下这些字符不算数(例如引号之间的字符)。

我认为每次需要执行此类操作时编写自定义逻辑可能会更好。

于 2008-08-13T18:49:40.020 回答
0

最简单的方法是将字符串拆分为 char 数组并查找您的字符串确定器并拆分 char。

单元测试应该相对容易。

您可以将其包装在类似于基本 .Spilt 方法的扩展方法中。

于 2008-08-13T18:57:16.790 回答