C# 从字符串中提取关键字并将其分配给C中的属性#

C# 从字符串中提取关键字并将其分配给C中的属性#,c#,C#,我需要将数据从MATLAB传输到C#软件。来自MATLAB的数据也应离线编辑(即,在MATLAB和C#软件之外)。为了实现这一点,我的MATLAB代码将具有可读模式的数据打印到文本文件中。例如: <L> pt: [0.001,2,3], spd: 100, cfg: fut, daq: on, id: [1,1] </L> <L> pt: [0.002,3,4], cfg: nut, spd: 100, id: [1,1], daq: on</L>

我需要将数据从MATLAB传输到C#软件。来自MATLAB的数据也应离线编辑(即,在MATLAB和C#软件之外)。为了实现这一点,我的MATLAB代码将具有可读模式的数据打印到文本文件中。例如:

<L> pt: [0.001,2,3], spd: 100, cfg: fut, daq: on, id: [1,1] </L>
<L> pt: [0.002,3,4], cfg: nut, spd: 100, id: [1,1], daq: on</L>
<C> pt: [0.02,5,3], spd: 100, daq: on, id: [1,1] </C>
<L> pt: [1.002,3,4], spd: 100, daq: off</L>
所以对于第1行,我打算让它看起来像这样:

var path = new Path {
    PathType = PathType.L,
    Pt = new []{ 0.001, 2, 3 },
    Spd = 100,
    Cfg = "fut",
    Daq = true,
    Id = new []{ 1, 1 }};
对于第4行:

var path = new Path {
    PathType = PathType.L,
    Pt = new []{ 1.002, 3, 4 },
    Spd = 100,
    Cfg = null,
    Daq = false,
    Id = null;
由于关键字按不同的顺序排列,并且可能不会出现在所有行中,因此我不能使用单个正则表达式来提取这些信息。我必须使用多个正则表达式来测试每一行:

    var typeReg = new Regex(@"<(\w+)>");
    var ptReg = new Regex(@"pt:\s+(?<open>\[)[^\[]*(?<close-open>\])(?(open))");
    var spdReg = new Regex(@"spd:\s+(\d+)");
    var cfgReg = new Regex(@"cfg:\s+(fut|nut)");
    var daqReg = new Regex(@"daq:\s+(on|off)");
    var idReg = new Regex(@"id:\s+(?<open>\[)[^\[]*(?<close-open>\])(?(open))");
然后我可以用分隔符
拆分字符串
,然后用
x.StartWith(“…”)
检查每个子字符串。但这样一来,我觉得它不如当前模式可读


我不想使用
xml
,因为它会使文本文件大于所需的大小。

我比较了JSON和xml,发现xml更好。我对XML格式的理解很差,认为它会显著增加文件大小,这是错误的


JSON实现

此方法需要一个NuGet包Newtonsoft.Json。还有其他不需要它的

MATLAB输出:

{"type":"L", "pt": "[0.001,2,3]", "spd": "100", "cfg": "fut", "daq": "on", "id": "[1,1]"}
<L pt='[0.001,2,3]' spd='100' cfg='fut' daq='on' id='[1,1]'  />
解码JSON的C#代码非常简单:

using Newtonsoft.Json;
public void Dictionary<string,string> DecodeJson(script)
{
    return JsonConvert.DeserializeObject(script);
}
使用Newtonsoft.Json;
公共无效字典解码JSON(脚本)
{
返回JsonConvert.DeserializeObject(脚本);
}
返回的对象是一个字典,由属性名组成,即type、pt、spd等作为键,属性值作为值

解码100k的示例输出大约需要330ms


XML实现

MATLAB输出:

{"type":"L", "pt": "[0.001,2,3]", "spd": "100", "cfg": "fut", "daq": "on", "id": "[1,1]"}
<L pt='[0.001,2,3]' spd='100' cfg='fut' daq='on' id='[1,1]'  />

C#代码:

公共无效字典解码XML(脚本)
{    
var xmlObj=新字典();
使用(var reader=XmlReader.Create(新建StringReader(脚本)))
{
reader.Read();
//添加节点名称,即xmlObj[“type”]->L
添加(“type”,reader.Name);
//添加所有属性
while(reader.MoveToNextAttribute())
{
Add(reader.Name,reader.Value);
}
}
返回xmlObj;
}
此方法返回与JSON方法相同的对象

解码100k的示例输出大约需要180毫秒


结论


xml实现的输入字符串比JSON实现的输入字符串短,因此文件大小更小。XML代码的执行时间几乎比JSON代码快2倍。因此,XML是一个更好的选择。

MATLAB正在创建这些字符串,或者您自己创建它们。如果您正在生成要解析的文件,那么如果您关心文件大小,请使用JSON而不是XML。如果MATLAB是这样生成的,那么你需要像你说的那样解析出拆分字符串。数据文件的当前形式有多大?就对象的大小和数量而言。@krillgar我在MATLAB中编写了一个代码来创建字符串。我可以随时更改它们以更好地适应我的C#代码。JSON听起来不错。“我会试试看。”拉塞夫·戈斯·瑟卡尔森说,目前只有几KB。我不想让它们变成几个MB:D
public void Dictionary<string,string> DecodeXml(script)
{    
    var xmlObj = new Dictionary<string, string>();
    using (var reader = XmlReader.Create(new StringReader(script)))
    {
        reader.Read();
        // add node name, i.e. xmlObj["type"] -> L
        xmlObj.Add("type",reader.Name);
        // add all attributes
        while (reader.MoveToNextAttribute())
        {
            xmlObj.Add(reader.Name, reader.Value);
        }
    }
    return xmlObj;
}