我需要解析具有以下结构的字符串
x:{a,b,c,},y:{d,e,f}等。
其中所有条目都是数字,所以它看起来像这样
411:{1,2,3},241:{4,1,2}等。
忘记提及:{}之间的逗号分隔条目数没有上限但必须至少有一个条目。
这可以用正则表达式完成吗?
答案 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*(?=:)