解析服务器的专有返回字符串
我需要从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位(!) 。
有没有分析这些类型的字符串(这同时我会得到同样的来自不同功能的字符串)
保罗
更合适的方式
//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;
谢谢@mad巫师你是一个真正的RegEx大师.. – 2014-09-19 08:09:05
这是一个优雅的解决方案,但正如你可以看到在响应中有不止一次出现的键(id,名字等)。我的猜测是它们代表两个记录,这两个记录是由〜字符分隔的。你应该在〜字符中分割字符串,然后在每个字符上使用正则表达式。至少可以说,这种专有响应格式的作者必须是一个误解的天才。 – Bedford 2014-09-19 08:10:33
@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;
}
}
}
}
哪里是一间完美的,但它的工程!
非常感谢你的解决方案!我不会拿你的,但再次感谢! – 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~
thanx为这个解决方案!我不会拿你的,但再次感谢! – 2014-09-19 08:24:52
为什么你猜?你没有关于这个字符串的含义以及它是如何构成的文档? – 2014-09-19 07:35:18
我想向这个专有格式字符串的创建者致意 – InferOn 2014-09-19 07:37:15
@ LasseV.Karlsen我猜测,虽然此格式的创建者已经在最新的固件中更改了某些内容,然后我的代码再也无法工作了(他们添加了另一个等号,在过去的名字的价值是在位置4) – 2014-09-19 07:43:42