我有这个字符串:
string Text = "{1}[56](17)(20)(13)(14)[895](11)(20)[3](8)(12)(3)[19](1)(2)(13)(7)(6)";
我必须退回:
Array ( [Type] => 1
[Items] => Array ( [56] => Array ( [1] => 17
[2] => 20
[3] => 13
[4] => 14 )
[895] => Array ( [1] => 11
[2] => 20 )
[3] => Array ( [1] => 8
[2] => 12
[3] => 3 )
[19] => Array ( [1] => 1
[2] => 2
[3] => 13
[4] => 7
[5] => 6 )
)
)
我该怎么做?我在php中取得了成功,但在c#中我无法找到解决方案。我先尝试过字典,但我无法达到它。我只是不知道如何使用具有多个值的键来制作字典也具有多个值。到目前为止,我做到了这一点:
var Menu_Matrix = new Dictionary<string, string>();
var Menu_Items = new Dictionary<string, List<string>>();
char[] sep1 = { '{', '}' };
char[] sep2 = { '[', ']' };
char[] sep3 = { '(', ')' };
string[] Menu_Id = new string [10];
string[] Category_Id = new string[20];
Menu_Id = Text.Split(sep1);
Menu_Matrix.Add("Type", Menu_Id[1]);
Category_Id = Menu_Id[2].Split(sep2);
int cat_len = 0;
cat_len = Category_Id.Length;
for (int i = 1; i < cat_len;i++)
{ int pos = 0;
if(Category_Id[i+1].IndexOf('(')!=-1)
pos=i+1;
if(pos>i)
{ var item = new List<string>();
string[] Item_id = new string[20];
Item_id = Category_Id[pos].Split(sep3);
for (int j = 1; j < Item_id.Length;j++ )
if(Item_id[j]!="")
item.Add(Item_id[j]);
Menu_Items.Add(Category_Id[i], item);
}
i = pos;
}
}
return Menu_Items;
结果是:
[56] => Array ( [1] => 17
[2] => 20
[3] => 13
[4] => 14 )
[895] => Array ( [1] => 11
[2] => 20 )
[3] => Array ( [1] => 8
[2] => 12
[3] => 3 )
[19] => Array ( [1] => 1
[2] => 2
[3] => 13
[4] => 7
[5] => 6 )
希望你知道我想说什么,请帮助我!我不关心我使用的是什么:字典,锯齿状数组或多维数组。
答案 0 :(得分:1)
我认为Dictionary<string, Dictionary<string, List<int>>>
是一个很好的结构来存储这些信息。
外部词典的关键是&#34; {#}&#34;
的值内部词典的关键是&#34; [#]&#34;
的值 List
内部Dictionary
中的值将是&#34;(#)&#34;的值,但没有括号
为了解析这些信息,我认为Regex.Split
的组合来获取外键和内键以及Regex.Match
以获取内键的值是一个很好的方法。
代码示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
public class Program
{
public static void Main()
{
string Text = "{1}[56](17)(20)(13)(14)[895](11)(20)[3](8)(12)(3)[19](1)(2)(13)(7)(6){2}[99](1)(2)(3)";
// Split out pairs
// 0: {#}
// 1: [#](#)..(n)
string[] splits = Regex.Split(Text, "({\\d+})").Where(split => !String.IsNullOrEmpty(split)).ToArray();
Dictionary<string, Dictionary<string, List<int>>> items = new Dictionary<string, Dictionary<string, List<int>>>();
for (int i = 0; i < splits.Length; i += 2)
{
// splits[i] is {#} which will make the key for this part of the Dictionary
items.Add(splits[i], new Dictionary<string, List<int>>());
items[splits[i]] = new Dictionary<string, List<int>>();
// Split out sub pairs
// 0: [#]
// 1: (#)..(n)
string[] subSplits = Regex.Split(splits[i + 1], "(\\[\\d+\\])").Where(subSplit => !String.IsNullOrEmpty(subSplit)).ToArray();
for (int j = 0; j < subSplits.Length; j += 2)
{
// subSplits[j] is [#] which will make the key for the inner Dictionary
items[splits[i]].Add(subSplits[j], new List<int>());
// subSplits[j + 1] is all of the (#) for each [#]
// which we'll add to the List of the inner Dictionary
Match m = Regex.Match(subSplits[j + 1], "(\\d+)");
while (m.Success)
{
items[splits[i]][subSplits[j]].Add(Convert.ToInt32(m.Groups[0].ToString()));
m = m.NextMatch();
}
}
}
// Print the keys of the Dictionary, the keys of the inner Dictionary, the values of the inner Dictionary
foreach (string key in items.Keys)
{
Console.WriteLine("Key: {0}", key);
foreach (string subKey in items[key].Keys)
{
Console.WriteLine("\t SubKey: {0}", subKey);
Console.WriteLine("\t\t Value: {0}", String.Join(", ", items[key][subKey]));
}
}
}
}
结果:
Key: {1}
SubKey: [56]
Value: 17, 20, 13, 14
SubKey: [895]
Value: 11, 20
SubKey: [3]
Value: 8, 12, 3
SubKey: [19]
Value: 1, 2, 13, 7, 6
Key: {2}
SubKey: [99]
Value: 1, 2, 3
请在此处查看工作示例... https://dotnetfiddle.net/Zt5gXc
答案 1 :(得分:0)
你可以考虑这样的事情:
string text = "{1}[56](17)(20)(13)(14)[895](11)(20)[3](8)(12)(3)[19](1)(2)(13)(7)(6)";
string[] tokens = text.Split(new Char[] { '}', ']', ')' });
char symbol;
int value;
Dictionary<int, Dictionary<int, List<int>>> data = new Dictionary<int, Dictionary<int, List<int>>>();
Dictionary<int, List<int>> items = null;
List<int> leaves = null;
foreach (string token in tokens) {
if (token.Length == 0) break;
symbol = token[0];
value = Int32.Parse(token.Substring(1));
switch (symbol) {
case '{':
items = new Dictionary<int, List<int>>();
data.Add(value, items);
break;
case '[':
leaves = new List<int>();
items.Add(value, leaves);
break;
case '(':
leaves.Add(value);
break;
}
}
foreach (int type in data.Keys)
{
Console.WriteLine("Type => {{{0}}}", type);
Console.WriteLine("\tItems =>");
items = data[type];
foreach (int item in items.Keys)
{
Console.WriteLine("\t\t[{0}] =>", item);
leaves = items[item];
for (int i = 0; i < leaves.Count; i += 1) {
Console.WriteLine("\t\t\t[{0}] => ({1})", i, leaves[i]);
}
}
}
See this working at DotNetFiddle.net
这会产生输出:
Type => {1}
Items =>
[56] =>
[0] => (17)
[1] => (20)
[2] => (13)
[3] => (14)
[895] =>
[0] => (11)
[1] => (20)
[3] =>
[0] => (8)
[1] => (12)
[2] => (3)
[19] =>
[0] => (1)
[1] => (2)
[2] => (13)
[3] => (7)
[4] => (6)
这是对其运作方式的破坏:
拆分结束标记(花括号,方括号或括号)上的所有数字。这会创建一个类似{ "{1", "[56", "(17", ... "(6", "" }
的数组。
为每个级别的数据结构创建一个变量,表示层次结构深度处的最后一个对象。
如果我们使用最后一个空白的令牌,请立即退出。
迭代拆分标记,并将表示数据结构层次结构级别的开始标记保存到symbol
,将数值保存到value
。
对于每个符号,请采取适当的措施。
巨大注意:此代码强烈期望输入字符串格式正确。例如,如果您传入字符串"{1}(17)"
,一切都会爆炸,因为没有中间[56]
来填充leaves
变量new List<int>
(
{{1}}代码期望已经实例化。