如何解析这个?

时间:2009-10-27 15:41:40

标签: c# regex

我需要解析具有以下结构的字符串

x:{a,b,c,},y:{d,e,f}等。

其中所有条目都是数字,所以它看起来像这样

411:{1,2,3},241:{4,1,2}等。

忘记提及:{}之间的逗号分隔条目数没有上限但必须至少有一个条目。

  1. 我需要获得唯一的列表 之前的数字:,在上述情况下     411241
  2. 这可以用正则表达式完成吗?

8 个答案:

答案 0 :(得分:8)

正则表达式:

(?<1>[\d]+):{(?<2>\d+),(?<3>\d+),(?<4>\d+)}

对于数据:

411:{1,2,3},241:{4,1,2},314:{5,6,7}

将生成以下匹配/组集合:

Match 0
Group 0: 411:{1,2,3}
Group 1: 411
Group 2: 1
Group 3: 2
Group 4: 3

Match 1
Group 0: 241:{4,1,2}
Group 1: 241
Group 2: 4
Group 3: 1
Group 4: 2

Match 2
Group 0: 314:{5,6,7}
Group 1: 314
Group 2: 5
Group 3: 6
Group 4: 7

您可以使用以下代码:

string expression = "(?<1>[\d]*):{(?<2>\d),(?<3>\d),(?<4>\d)}";
string input = "411:{1,2,3},241:{4,1,2},314:{5,6,7}";

Regex re = new Regex(expression, RegexOptions.IgnoreCase);

MatchCollection matches = re.Matches(input);

for (int i = 0; i < matches.Count; i++)
{
Match m = matches[i];
// for i==0
// m.groups[0] == 411:{1,2,3}
// m.groups[1] == 411
// m.groups[2] == 1
// m.groups[3] == 2
// m.groups[4] == 4
}

<强>更新 无法让它与列表中的纯正则表达式和可变数量的项目一起工作 - 也许其他人可以在此处插入。一个简单的解决方案是:

string expression = "(?<1>[\d]+):{(?<2>[\d,?]+)}";
string input = "411:{1,2,3,4,5},241:{4,1,234}";

Regex re = new Regex(expression, RegexOptions.IgnoreCase);

MatchCollection matches = re.Matches(input);

for (int i = 0; i < matches.Count; i++)
{
Match m = matches[i];
// for i==0
// m.groups[0] == "411:{1,2,3}"
// m.groups[1] == "411"
// m.groups[2] == "1,2,3"
int[] list = m.Groups[1].Split(",");
// now list is an array of what was between the curly braces for this match
}

上面的匹配列表:

Match 0
Group 0: 411:{1,2,3,4,5}
Group 1: 411
Group 2: 1,2,3,4,5

Match 1
Group 0: 241:{4,1,234}
Group 1: 241
Group 2: 4,1,234

答案 1 :(得分:2)

为什么要用正则表达式执行此操作?我的意思是,你正在查询id的字符串并给出一个id,想要检索它的值。我只是打破了字符串并创建了一个以id为键的地图结构,以及一组数字作为其值。

答案 2 :(得分:1)

我认为这可能有用,Pseudo-Code

foreach match in Regex.Matches(yourInputString, "[0-9]{3}:\{[0-9,]\},")
    firstNumber = match.Value.Substring(0, 3)
    numbers() = match.Value.Substring(4, match.Value.Length - 5).Split(",")
next

答案 3 :(得分:1)

如果我们考虑x:{a,b,c}一个元素,下面将给出一个匹配列表,其中包含两个命名的grounps:Outer和Inner。外面是x,内在是a,b,c。

(?<outer>\d+):\{(?<inner>\d+(,\d+)*)\}

更新

以下是代码示例:

        String input = "411:{1,2,3},241:{4,1,2},45:{1},34:{1,34,234}";
        String expr = @"(?<outer>\d+):\{(?<inner>\d+(,\d+)*)\}";

        MatchCollection matches = Regex.Matches(input, expr);

        foreach (Match match in matches)
        {
            Console.WriteLine("Outer: {0} Inner: {1}", match.Groups["outer"].Value, match.Groups["inner"]);
        }

答案 4 :(得分:1)

此字符串具有json格式。所以你可以使用Json.Net为你解析它

答案 5 :(得分:1)

你在使用JSON吗?如果是这样,您可能想要查看MSDN上的JavaScriptSerializer类,

http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx

答案 6 :(得分:1)

这是一种没有RegEx的替代方案,可以更快地运行。

这会返回Dictionary<Double, List<Double>> ....

public Dictionary<double, List<double>> Example()
        {
            String[] aSeparators = {"{", "},", ",", "}"};
            String data = "411:{1,2,3},843:{6,5,4,3,2,1},241:{4,1,2}";
            String[] bases = data.Split(aSeparators, StringSplitOptions.RemoveEmptyEntries);
            Dictionary<double, List<double>> aDict = null;

            double aHeadValue = 0;
            List<Double> aList = null;
            foreach (var value in bases)
            {
                if (value.EndsWith(":"))
                {
                    if (aDict == null)
                        aDict = new Dictionary<double, List<double>>();
                    else
                        aDict.Add(aHeadValue, aList);
                    aHeadValue = Double.Parse(value.TrimEnd(':'));
                    aList = new List<Double>();
                }
                else
                {
                    aList.Add(Double.Parse(value));
                }
            }
            aDict.Add(aHeadValue, aList);
            return aDict;
        }

答案 7 :(得分:-2)

第一个可以使用以下正则表达式实现:

\d*(?=:)