我最初看起来似乎是一个微不足道的问题,但结果却成了我无法弄清楚如何轻松解决的问题。我需要能够在字符串中存储项目列表。然后,这些项目可以成为列表,或其他可能包含我的分隔符的值。我有两种不同的方法可以解压缩两种不同的情况,但我意识到我需要对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做扩展,我只能使用整数,浮点数和字符串。因此我选择字符串作为我的数据载体。这就是我制作这个嵌套字符串列表的原因。
答案 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:约翰
缺点是它明确要求所有项目的长度,即使不存在“共享分隔符”字符(如果使用固定长度标题,此解决方案不使用分隔符)。
答案 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;
}