反序列化包含重复元素集的字符串

时间:2011-10-05 11:25:23

标签: c# asp.net

我收到的响应字符串如下:

Navigator[sizenavigator:INTEGER (Size) 
          modifier:size
          score:1.300855517 type:INTEGER unit:kB
          hits:7744 
          hitsUsed:7744 
          ratio:1
          min:65 
          max:66780 
          mean:3778
          sum: 29259942
          frequencyError:-1
          entropy:1.300855533 
          points:
          Name:Less than 1 
          Interval: ->1023 
          Value:[;1023] 
          Count:1121
          Name:Between 1 and 2 
          Interval: 1024->2047 
          Value:[1024;2047] 
          Count:3325
          Name:Between 2 and 3 
          Interval: 2048->3071 
          Value:[2048;3071] 
          Count:1558
          Name:More than 3 
          Interval: 3072-> 
          Value:[3072;] 
          Count:1740
         ]

正如您所见,名称,间隔,值,计数正在重复,这将重复'n'否。时间。如何通过为此过程创建类型(类)来对其进行反序列化?

说这个班级是否有点像:

class Navigator
{
 string modifier;
 string score;
 .
 .
 string Name;
 string Interval;
 string Value;
 int Count;
}

我们如何获得名称,间隔,值,计数的重复值

提前致谢。

2 个答案:

答案 0 :(得分:3)

我建议您自由使用正则表达式来提取所需的信息。这增加了很多复杂性,但是你的另一个选择是tokenisation,在给定输入的情况下,IMO将同样复杂。

修饰符的正则表达式非常简单。它要求您查找文字字符串“modifier:”并捕获:之后的任何内容,直到行结束 - 由cr \r\n标记。您可以使用捕获组来提取所需的信息,以便正则表达式为:

modifier:(.*[^\r\n])

得分的正则表达式同样简单,查找文字字符串score:并捕获:之后的所有内容直到该行的结尾:

score:(.*[^\n\r])

你的重复项的正则表达式要复杂得多,并且再次利用捕获组(这次命名以使它们更容易提取它们)来获取你感兴趣的信息。这是经过测试和工作的:< / p>

Name:\s*(?<name>.*[^\r\n])\s*\r\n\s+Interval:\s(?<interval>\d*\-\>\d*)\s*\r\n\s+Value:\s*(?<value>\[\d*;\d*\])\s*\r\n\s+Count:\s*(?<count>\d+) 

根据名为input的变量中的输入数据,您将使用以下代码:

var modifierRegex = new Regex(@"modifier:(.*[^\r\n])");
var scoreRegex = new Regex(@"score:(.*[^\n\r])");
var itemsRegex = new Regex(@"Name:\s*(?<name>.*[^\r\n])\s*\r\n\s+Interval:\s(?<interval>\d*\-\>\d*)\s*\r\n\s+Value:\s*(?<value>\[\d*;\d*\])\s*\r\n\s+Count:\s*(?<count>\d+)");
var modifierMatch = modifierRegex.Match(input);
var scoreMatch = scoreRegex.Match(input);
var itemsMatches = itemsRegex.Matches(input);

var modifier = modifierMatch.Groups[1].Value;
var score = scoreMatch.Groups[1].Value;
foreach(Match match in itemsMatches)
{
  var name = match.Groups["name"].Value;
  var interval = match.Groups["interval"].Value;
  var value = match.Groups["value"].Value;
  var count = match.Groups["count"].Value;
}

实例:http://rextester.com/rundotnet?code=OQTZE85773

它向您展示了如何提取所需的值。现在使用诸如described by @Jeremy McGee之类的数据结构,并按照他描述的那样读取值。

答案 1 :(得分:2)

我认为您正在寻找的是将文本字符串转换为某种内部C#数据结构的方法。对于重复结构,您需要两个类:一个用于文本的“主”主体,另一个用于重复项目:

class Navigator
{
 string modifier;
 string score;
 .
 .
 List<IntervalItem> Intervals;
}

class IntervalItem
{
    string Name;
    string Interval;
    string Value;
    int Count;
}

然后在反序列化文本的代码中,例如:

Navigator navigator = new Navigator();
// ... populate the modifier, score, and suchlike
navigator.Intervals = new List<IntervalItem>();

while ( // something to test if we have an interval to read // )
{
  IntervalItem intervalItem = new IntervalItem();
  // ... populate the interval from the name, interval, value
  navigator.Intervals.Add(intervalItem);
}

(你需要找出一种合适的方法来测试你是否有另一个间隔时间来根据你在文本中的扫描方式进行阅读。)