我需要从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位。
是否有更合适的方法来解析这些类型的字符串(这些我将从不同的函数中获得相同类型的字符串)
保
答案 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~