解析服务器的专有返回字符串

问题描述:

我需要从tcp服务器解析专有字符串。 字符串我得到的是如下:解析服务器的专有返回字符串

!re.tag=3=.id=*1=name=1 Hour=owner=admin=name-for-users==validity=3h=starts-at=logon=price=0=override-shared-users=off~!re.tag=3=.id=*2=name=3 Hour=owner=admin=name-for-users==validity=3h=starts-at=logon=price=0=override-shared-users=off~!done.tag=3~ 

所以当条带化掉done.tag ....和分裂字符串的〜我可以(在这种情况下)两个对象分解到

!re.tag=3=.id=*1=name=1 Hour=owner=admin=name-for-users==validity=3h=starts-at=logon=price=0=override-shared-users=off~ 
!re.tag=3=.id=*2=name=3 Hour=owner=admin=name-for-users==validity=3h=starts-at=logon=price=0=override-shared-users=off~ 

然后即时通讯面临的问题,如何拆分属性和它们的值。

!re.tag=3 
=.id=*2 
=name=3 Hour 
=owner=admin 
=name-for-users= 
=validity=3h 
=starts-at=logon 
=price=0 
=override-shared-users=off 

通常,我会做一个分割上等号,就像这样:

List<string> arProfiles = profilString.Split('=').ToList(); 

,然后我可以猜测,“名”的价值属性是第5位(!) 。

有没有分析这些类型的字符串(这同时我会得到同样的来自不同功能的字符串)

保罗

更合适的方式
+2

为什么你猜?你没有关于这个字符串的含义以及它是如何构成的文档? – 2014-09-19 07:35:18

+1

我想向这个专有格式字符串的创建者致意 – InferOn 2014-09-19 07:37:15

+0

@ LasseV.Karlsen我猜测,虽然此格式的创建者已经在最新的固件中更改了某些内容,然后我的代码再也无法工作了(他们添加了另一个等号,在过去的名字的价值是在位置4) – 2014-09-19 07:43:42

//so. we've got the response here 
var response = "!re.tag=3=.id=*1=name=1 Hour=owner=admin=name-for-users==validity=3h=starts-at=logon=price=0=override-shared-users=off~!re.tag=3=.id=*2=name=3 Hour=owner=admin=name-for-users==validity=3h=starts-at=logon=price=0=override-shared-users=off~!done.tag=3~"; 

// first we split the line into sections 
var sections = Regex.Matches(response, @"!(?<set>.*?)~").Cast<Match>().Select(s=>s.Groups["set"].Value).ToArray(); 

// next we can parse any section into key/value pairs 
var parsed = Regex.Matches(sections[0], @"(?<key>.*?)=(?<value>[^=]*)=?").Cast<Match>() 
    .Select(pair => new 
    { 
     key = pair.Groups["key"].Value, 
     value = pair.Groups["value"].Value, 
    }).ToArray(); 

不要忘记

using System.Text.RegularExpressions; 
+0

谢谢@mad巫师你是一个真正的RegEx大师.. – 2014-09-19 08:09:05

+0

这是一个优雅的解决方案,但正如你可以看到在响应中有不止一次出现的键(id,名字等)。我的猜测是它们代表两个记录,这两个记录是由〜字符分隔的。你应该在〜字符中分割字符串,然后在每个字符上使用正则表达式。至少可以说,这种专有响应格式的作者必须是一个误解的天才。 – Bedford 2014-09-19 08:10:33

+0

@Bedfold有'sections'变量,它包含单独的记录,所以每个部分中的每个键都是唯一的。 – 2014-09-19 08:14:18

每个参数名称以'='符号开头和结尾。这意味着你需要处理字符串来查找两个'='之间的第一个值。在那之后以及在下一个'='符号或字符串的结尾是该属性的值之前将会发生。属性可能有一个空值,所以它也必须处理。

字符串的第一部分是不同的:

!re.tag=3 

你必须删除或单独处理它。

方法来分析这将是:

var inString = @"=.id=*1=name=1 Hour=owner=admin=name-for-users==validity=3h=starts-at=logon=price=0=override-shared-users=off~"; 

     int startOfParameterName = 0; 
     int endOfParameterName = 0; 
     int startOfParameterValue = 0; 

     bool paramerNameEndFound = false; 
     bool paramerNameStartFound = false; 

     var arProfiles = new Dictionary<string, string>(); 

     for(int index = 0; index < inString.Length; index++) 
     { 
      if (inString[index] == '=' || index == inString.Length - 1) 
      { 
       if (paramerNameEndFound || index == inString.Length - 1) 
       { 
        var parameterName = inString.Substring(startOfParameterName, endOfParameterName - startOfParameterName); 
        var parameterValue = startOfParameterValue == index ? string.Empty : inString.Substring(startOfParameterValue, index - startOfParameterValue); 

        arProfiles.Add(parameterName, parameterValue); 

        startOfParameterName = index + 1; 
        paramerNameEndFound = false; 
        paramerNameStartFound = true; 
       } 
       else 
       { 
        if (paramerNameStartFound == false) 
        { 
         paramerNameStartFound = true; 
         startOfParameterName = index + 1; 
        } 
        else 
        { 
         paramerNameEndFound = true; 
         endOfParameterName = index; 
         startOfParameterValue = index + 1; 
        } 
       } 

      } 
     } 

哪里是一间完美的,但它的工程!

+0

非常感谢你的解决方案!我不会拿你的,但再次感谢! – 2014-09-19 08:24:15

好像每个(未参数名)由一对 “=” 的包围。

这应该给你想要的东西,或多或少:

var input = "!re.tag=3=.id=*1=name=1 Hour=(...etc...)"; 

Dictionary<string, string> values = new Dictionary<string, string>(); 

while(input.Count() > 0){ 
    var keyChars = input.TakeWhile(x=> x != '='); 
    var currTag = new string(keyChars.ToArray()); 

    var valueChars = input.Skip(currTag.Count() + 1).TakeWhile(x=> x != '='); 
    var value = new string(valueChars.ToArray()); 

    values.Add(currTag, value); 
    input = new string(input.Skip(currTag.Length + value.Lenght + 2) 
          .ToArray()); 
} 

这将导致以下键和值:

!re.tag    | 3 
.id     | *1 
name     | 1 Hour 
owner     | admin 
name-for-users  | 
validity    | 3h 
starts-at    | logon 
price     | 0 
override-shared-users | off~ 
+0

thanx为这个解决方案!我不会拿你的,但再次感谢! – 2014-09-19 08:24:52