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

时间:2014-09-19 07:33:49

标签: c# linq

我需要从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();

然后我可以猜测(!)&#34; name&#34;的值物业位于第5位。

是否有更合适的方法来解析这些类型的字符串(这些我将从不同的函数中获得相同类型的字符串)

3 个答案:

答案 0 :(得分:4)

//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;

答案 1 :(得分:0)

每个参数名称以'='符号开头和结尾。这意味着你需要处理字符串,寻找两个'='之间的第一个值。之后将会出现在下一个'='符号或字符串结尾之前的那个属性的值。属性可能具有空值,因此也必须处理它。

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

!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;
                    }
                }

            }
        }

在哪里有完美的空间,但它有效!

答案 2 :(得分:0)

似乎每个(不是参数名称)都被一对“=”包围。

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

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~