如何进行嵌套字符串拆分?

时间:2011-03-05 11:48:56

标签: c# string

我最初看起来似乎是一个微不足道的问题,但结果却成了我无法弄清楚如何轻松解决的问题。我需要能够在字符串中存储项目列表。然后,这些项目可以成为列表,或其他可能包含我的分隔符的值。我有两种不同的方法可以解压缩两种不同的情况,但我意识到我需要对string.Split中使用的任何分隔符进行编码。

为了说明问题:

string[] nested = { "mary;john;carl", "dog;cat;fish", "plainValue" }
string list = string.Join(";", nested);
string[] unnested = list.Split(';'); // EEK! returns 7 items, expected 3!

这将生成一个列表“mary; john; carl; dog; cat; fish; plainValue”,这是一个我无法拆分的值,以获取三个原始的嵌套字符串。实际上,我不会使用三个原始字符串,而是在分割时得到7个字符串,因此这种方法根本不起作用。

我想要的是允许对我的字符串中的值进行编码,这样我就可以在打包/加入之前解压/拆分内容。 我想我可能需要远离string.Split和string.Join,这很好。我可能只是忽略了一些有用的类或方法。

  • 如何允许将任何字符串值打包/解压缩到列表中? 如果可能的话,我更喜欢整洁,简单的解决方案。

对于好奇的头脑,我在Unity3D中为PlayerPrefs做扩展,我只能使用整数,浮点数和字符串。因此我选择字符串作为我的数据载体。这就是我制作这个嵌套字符串列表的原因。

7 个答案:

答案 0 :(得分:2)

尝试:

const char joinChar = '╗'; // make char const
string[] nested = { "mary;john;carl", "dog;cat;fish", "plainValue" };
string list = string.Join(Convert.ToString(joinChar), nested);
string[] unnested = list.Split(joinChar); // eureka returns 3!

使用普通'set'之外的ascii字符可以加入和分割,而不会破坏; char上分隔的逻辑。

答案 1 :(得分:1)

预期的项目为7,因为您正在使用;字符进行拆分。我建议将您的代码更改为:

string[] nested = { "mary;john;carl", "dog;cat;fish", "plainValue" }
string list = string.Join("@" nested);
string[] unnested = list.Split('@'); // 3 strings again

答案 2 :(得分:1)

您是否考虑使用其他分隔符,例如“|”?

这样连接的字符串将是“mary; john; carl | dog; cat; fish | plainValue”,当你调用list.split(“|”)时;它将返回三个原始字符串

答案 3 :(得分:1)

在加入之前使用base64编码对字符串进行编码。

答案 4 :(得分:0)

使用除分号(;)之外的其他值来加入。例如 - 您可以使用逗号(,),然后获得"mary;john;carl,dog;cat;fish,plainValue"。当您再次基于(,)将其拆分为分隔符时,您应该恢复原始字符串值。

答案 5 :(得分:0)

我想出了一个我自己的解决方案。

我可以编码项目的长度,然后是项目的内容。它根本不会使用string.Split和string.Join,但它可以解决我的问题。内容将不受影响,任何需要编码的内容都可以在其内容空间中使用此编码。

说明格式(常量标题):

  

<内容长度> <原始内容>

说明格式(可变长度标题):

  

<内容长度> <标题停止字符> <原始内容>

在前者中,使用固定长度的字符来描述内容的长度。这可以是纯文本,十六进制,base64或其他一些编码。

4个十六进制的示例(ffff / 65535最大长度):

  

0005Hello0005World

在后一个示例中,我们可以将其减少为:

  

5:Hello5:世界

然后我可以查找:的第一次出现并首先解析长度,以提取后面的子字符串。之后是列表的下一个项目。

嵌套示例可能如下所示:

  

E:5:Hello5:Worlda:2:HI4:约翰

  • (列表 - 包含标题的14个字符)
    • 您好(5个字符)
    • 世界(5个字符)
  • (列表 - 包含标题的10个字符)
    • 嗨(2个字符)
    • 约翰(4个字符)

缺点是它明确要求所有项目的长度,即使不存在“共享分隔符”字符(如果使用固定长度标题,此解决方案不使用分隔符)。

答案 6 :(得分:0)

Maby并不像你想的那么好。但这里有:)

    static void Main(string[] args)
    {
        string[] str = new string[] {"From;niklas;to;lasse", "another;day;at;work;", "Bobo;wants;candy"};
        string compiledString = GetAsString(str);
        string[] backAgain = BackToStringArray(compiledString);
    }

    public static string GetAsString(string[] strings)
    {
        string returnString = string.Empty;
        using (MemoryStream ms = new MemoryStream())
        {
            using (BinaryWriter writer = new BinaryWriter(ms))
            {
                writer.Write(strings.Length);
                for (int i = 0; i < strings.Length; ++i)
                {
                    writer.Write(strings[i]);
                }
            }
            ms.Flush();

            byte[] array = ms.ToArray();
            returnString = Encoding.UTF8.GetString(array);
        }
        return returnString;
    }

    public static string[] BackToStringArray(string encodedString)
    {
        string[] returnStrings = new string[0];
        byte[] toBytes = Encoding.UTF8.GetBytes(encodedString);
        using (MemoryStream stream = new MemoryStream(toBytes))
        {
            using (BinaryReader reader = new BinaryReader(stream))
            {
                int numStrings = reader.ReadInt32();
                returnStrings = new string[numStrings];
                for (int i = 0; i < numStrings; ++i)
                {
                    returnStrings[i] = reader.ReadString();
                }
            }
        }
        return returnStrings;
    }