LDF转Excel;LDF转位定义;Excel转LDF;Excel转位定义;MatrixCreat(三)之LDF文件详解

本文深入剖析LDF文件格式,涵盖版本、波特率、节点、信号等关键元素,详述C#解析技巧,助您高效处理汽车通讯数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、摘要

1.描述

本文主要描述的是汽车行业中LDF文件的格式,如何去解析它,如何通过文本编辑器去修改它,了解LDF文件之前如果不懂LDF的请去查看我之前的博客。

2.关键字

LDF,LDF解析,LDF数据库,LDF文件,C#解析LDF文件。

二、为什么要了解LDF文件

LDF文件在汽车行业应用十分广泛,如果编辑LDF文件我们都使用Vector工具DF Explorer Pro或者LDFEditor去编辑,那效率将会是十分的低下,当我们了解了LDF文件的构成后,我们可以通过其他方式进行解析,可以大大的提高工作的效率,我们可以通过记事本或者其他工具打开LDF文件。

三、LDF文件构成

1.版本

关键字:LIN_protocol_version
格式:LIN_protocol_version = “version”;
格式中的version就是版本信息,版本信息可以为空,但是不能省略""符。
例如:LIN_protocol_version = “2.1”;代表版本号为V2.1。
在这里插入图片描述

2.波特率

关键字:LIN_speed
格式:LIN_speed = baudrate;
格式中的baudrate就是波特率。
例如:LIN_speed = 19.2 kbps;;代表波特率为19200。
在这里插入图片描述

3.节点信息

关键字:Nodes
格式:Nodes {
        Master: name1 jitter ms, timebase ms ;
        Slaves: name2,name3…;
      }

name1:主节点名称。
jitter:偏移是指一帧报文实际开始发送的时刻与帧时隙起点的时间差。
timebase:时间基数
name2,name3…:代表接收节点名称。
例如:Nodes {
        Master: GW_BCM, 1 ms, 0 ms ;
        Slaves: LIN_RLS,Tellus_Node;
      }
代表主节点名称为BCM,偏移为1ms,时间基数为0ms,从节点名称为LIN_RLS和Tellus_Node。
在这里插入图片描述

4.信号信息

关键字:Signals
格式:Signals {
        Signal_Name: Bit_Length, Signal_Init_Value, name1, name2… ;
        …;
      }

Signal_Name:信号名称,命名规则和C语言变量相同。
Bit_Length:信号的长度,范围为1-64。
Signal_Init_Value:信号初始值。
name1,name2…:代表接收节点名称。
例如:Signals {
        BCM_WiperRunning: 1, 0, GW_BCM, LIN_RLS ;
        RLS_MessageCounter: 4, 0, LIN_RLS, GW_BCM;
      }
代表信号名称为BCM_WiperRunning的长度为1,初始值为0,接收节点有GW_BCM, LIN_RLS;
信号名称为RLS_MessageCounter的长度为4,初始值为0,接收节点有LIN_RLS, GW_BCM;
在这里插入图片描述

5.诊断信号信息

关键字:Diagnostic_signals
格式:Diagnostic_signals{
        Signal_Name: Bit_Length, Signal_Init_Value ;
        …;
      }

Msg_ID:报文标识符,十进制表示。
Msg_Name:报文名称,命名规则和C语言变量相同。
Msg_Length :报文长度,长度范围为0-8。
例如:Diagnostic_signals{
        MasterReqB0: 8, 0 ;
        MasterReqB1: 8, 0 ;
        MasterReqB2: 8, 0 ;
        MasterReqB3: 8, 0 ;
        MasterReqB4: 8, 0 ;
        MasterReqB5: 8, 0 ;
        MasterReqB6: 8, 0 ;
        MasterReqB7: 8, 0 ;
        SlaveRespB0: 8, 0 ;
        SlaveRespB1: 8, 0 ;
        SlaveRespB2: 8, 0 ;
        SlaveRespB3: 8, 0 ;
        SlaveRespB4: 8, 0 ;
        SlaveRespB5: 8, 0 ;
        SlaveRespB6: 8, 0 ;
        SlaveRespB7: 8, 0 ;
      }
诊断报文一般自动生成的格式基本不变,也可以做一定名字调整等。
在这里插入图片描述

6.报文消息

关键字:Frames
格式:Frames {
        Msg_Name: Msg_ID, Msg_Transmitter, Msg_Length {
          Signal_Name, Start_Bit;
          …;
        };
        …;
      }

Msg_Name:报文名称,命名规则和C语言变量相同。
Msg_ID:报文标识符,十进制或者十六进制表示。
Msg_Transmitter:发送节点。
Msg_Length :报文长度,长度范围为0-8。
Signal_Name:信号名称,命名规则和C语言变量相同。
Start_Bit:信号的起始位,范围为0-63。
例如:Frames {
        BCM_data: 21, GW_BCM, 8{
          BCM_WiperRunning, 23;
        }
        RLS_data: 13, LIN_RLS, 8{
          RLS_MessageCounter, 0;
        }
      }
代表报文名称BCM_data的ID为0x15,长度为8,发送节点为GW_BCM,包含信号名称为BCM_WiperRunning,该信号起始位为23;
报文名称RLS_data的ID为0x0D,长度为8,发送节点为LIN_RLS,包含信号名称为RLS_MessageCounter,该信号起始位为0;
在这里插入图片描述

7.诊断报文消息

关键字:Diagnostic_frames
格式:Diagnostic_frames {
        MasterReq: Msg_ID{
          Signal_Name, Start_Bit;
          …;
        };
        SlaveResp: Msg_ID{
          Signal_Name, Start_Bit;
          …;
        };
      }

Msg_ID:报文标识符,十进制或者十六进制表示。
Msg_Length :报文长度,长度范围为0-8。
Signal_Name:信号名称,命名规则和C语言变量相同。
Start_Bit:信号的起始位,范围为0-63。
例如:Diagnostic_frames {
        MasterReq: 0x3c {
          MasterReqB0, 0;
          MasterReqB1, 8;
          MasterReqB2, 16;
          MasterReqB3, 24
          MasterReqB4, 32;
          MasterReqB5, 40;
          MasterReqB6, 48;
          MasterReqB7, 56;
        }
        SlaveResp: 0x3d {
          SlaveRespB0, 0;
          SlaveRespB1, 8;
          SlaveRespB2, 16;
          SlaveRespB3, 24
          SlaveRespB4, 32;
          SlaveRespB5, 40;
          SlaveRespB6, 48;
          SlaveRespB7, 56;
        }
      }
在这里插入图片描述

8.从节点信息

  • 关键字:Node_attributes
    格式:BA_DEF_ Object AttributeName ValueType Min Max;”
    Object:注解的对象类型,可以是节点“BU_”、报文“BO_”、消息”SG_”、网络节点” ”(用空格表示)。
    AttributeName: 自定义属性名称,命名规则和C语言变量相同。
    ValueType:属性值的类型,可以是整型、字符串、浮点型、枚举类型等。
    Min:属性值的最小值(字符串类型没有此项)。
    Min:属性值的最大值(字符串类型没有此项)。
    例如:BA_DEF_ “ECU” STRING ;代表自定义网络节点属性名称为ECU,类型为字符串型。
    BA_DEF_ BO_ “MsgCycleTime” INT 0 1000;代表自定义报文属性名称为MsgCycleTime,类型为整型,取值范围为0-1000。

9.调度表

  • 关键字:Node_attributes
    格式:BA_DEF_ Object AttributeName ValueType Min Max;”
    Object:注解的对象类型,可以是节点“BU_”、报文“BO_”、消息”SG_”、网络节点” ”(用空格表示)。
    AttributeName: 自定义属性名称,命名规则和C语言变量相同。
    ValueType:属性值的类型,可以是整型、字符串、浮点型、枚举类型等。
    Min:属性值的最小值(字符串类型没有此项)。
    Min:属性值的最大值(字符串类型没有此项)。
    例如:BA_DEF_ “ECU” STRING ;代表自定义网络节点属性名称为ECU,类型为字符串型。
    BA_DEF_ BO_ “MsgCycleTime” INT 0 1000;代表自定义报文属性名称为MsgCycleTime,类型为整型,取值范围为0-1000。

10.描述信息

关键字:Signal_encoding_types
格式:Signal_encoding_types {
        Signal_Encoding{
          physical_value, Min, Max, Factor, Offset,“Unit” ;
          logical_value, N, “DefineN;
          …;
        };
        …;
      }

Signal_Encoding:信号描述定义名称,命名规则和C语言变量相同。
N:定义的数值表内容。
Min:属性值的最小值(十进制)。
Min:属性值的最大值(十进制)。
Factor:精度。
Offset:偏移量,Factor和Offset这两个值于该信号的原始值与物理值之间的转换,转换如下:物理值=原始值*因子+偏移量。
DefineN:数值表内容对应该信号的有效值分别用什么符号表示。
Unit:信号的单位,为字符串类型,可以省略,省略时“,”也要省略。
例如:Signal_encoding_types{
        BCM_AMP_Driver_Encoding {
          physical_value, 0, 7, 1, 0 ;
          logical_value, 0, “No input” ;
          logical_value, 1, “Manual Up” ;
          logical_value, 2, “Manual Down” ;
        }
      }
代表描述信号名称为BCM_AMP_Driver_Encoding 的最小值为0,最大值为7,精度为1,偏移量为0,定义0x00表示为"No input" ,0x01表示为"Manual Up" ,0x02表示为"Manual Down" 。
在这里插入图片描述

11.信号描述关联

关键字:Signal_representation
格式:Signal_representation {
        Signal_Encoding: Signal_Name1, Signal_Name2…;
        …
      }

Signal_Encoding:信号描述定义名称,命名规则和C语言变量相同。
Signal_Name1,Signal_Name2…:信号定义名称,命名规则和C语言变量相同。
例如:Signal_representation {
        BCM_AMP_Driver_Encoding: BCM_AMP_Driver ;
        BCM_DRV_SWITCH_COOL_Encoding: BCM_DRV_SWITCH_COOL ;
      }
代表信号名称为BCM_AMP_Driver 的信号定义是BCM_AMP_Driver_Encoding的内容;
BCM_DRV_SWITCH_COOL_Encoding的信号定义是BCM_DRV_SWITCH_COOL 的内容。
在这里插入图片描述

四、LDF文件解析

通过以上描述,我相信各位对LDF文件的结构有一定的了解,但是我们如何去解析呢,很多人第一时间想到的应该是按行解析,其实LDF文件有许多容错处理,单纯按行解析我们会错过许多细节部分,例如下图其实也没有出错,如果按行解析的话报文就解析不到了。还有很多类似的容错处理在里面,所以单纯按行解析是不行的,并且有的时候也是不能通过空格来分开数据的,比如带有“”的前后是可以不追加空格的。
在这里插入图片描述
经过好久的挣扎,查询资料,终于在一个博客的找到了一种解析的方式,通过正则表达式去解析,当然他其实是按行解析,其实会丢掉一些数据,我将方法进行了一些简单的优化,先读取整个文件到字符串,把多行空格转换成一行空格,然后把换行符转换成空格符,然后进行查找,然后按照标准进行拆分。我这边解析的主要使用的C#语言,因为C#语言对字符串有友好的操作,我将部分代码粘贴如下,方便大家参考学习。

1.解析版本

       /**********************************************/
        ///<summary>
        ///Name    :AnalysisVersion
        ///Author  :WangHu
        ///Function:***
        ///Version :V1.0.0
        ///Data    :2022.5.20
        ///</summary>
        /**********************************************/
        private static bool AnalysisVersion(MsgInfo_Type msgInfo, string data)
        {
            string pattern = "LIN_protocol_version([ ]*)(=)([ ]*)\"((([^\"\\s])|([\\s\\u4e00-\\u9fa5]))*)\"([ ]*);";
            MatchCollection matchs = Regex.Matches(data, pattern);
            foreach (Match match in matchs)
            {
                if (matchs.Count == 1)
                {
                    string[] array = match.Value.Split(new string[] { @"""" }, StringSplitOptions.RemoveEmptyEntries);
                    if (array.Length >= 2) { msgInfo.version = array[1]; }
                    return true;
                }
            }
            return true;
        }

2.解析节点信息

       /**********************************************/
        ///<summary>
        ///Name    :AnalysisNodes
        ///Author  :WangHu
        ///Function:***
        ///Version :V1.0.0
        ///Data    :2022.5.20
        ///</summary>
        /**********************************************/
        private static bool AnalysisNodes(MsgInfo_Type msgInfo, string data)
        {
            string pattern = "(Nodes[ ]*){[^{}]*}";
            foreach (Match match in Regex.Matches(data, pattern))
            {
                string masterPattern = "(Master[ ]*):([ ]*\\w+[ ]*),([ ]*(\\.|\\w|[ ])+[ ]*),([ ]*(\\.|\\w|[ ])+[ ]*);";
                foreach (Match masterMatch in Regex.Matches(match.Value, masterPattern))
                {
                    string[] array = masterMatch.Value.Split(new string[] { " ", ":", ",", ";" }, StringSplitOptions.RemoveEmptyEntries);
                    msgInfo.master = array[1];
                }
                string slavesPattern = "(Slaves[ ]*):([ ]*\\w+[ ]*)(,[ ]*\\w+[ ]*)*;";
                foreach (Match slavesMatch in Regex.Matches(match.Value, slavesPattern))
                {
                    string[] array = slavesMatch.Value.Split(new string[] { " ", ":", ",", ";" }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < array.Length - 1; i++) { msgInfo.slaves.Add(array[i + 1]); }
                }
            }
            return true;
        }

3.解析调度表

       /**********************************************/
        ///<summary>
        ///Name    :AnalysisScheduleTables
        ///Author  :WangHu
        ///Function:***
        ///Version :V1.0.0
        ///Data    :2022.5.20
        ///</summary>
        /**********************************************/
        private static bool AnalysisScheduleTables(MsgInfo_Type msgInfo, string data)
        {
            string pattern = "(Schedule_tables[ ]*){(([^{}]*{[^{}]*})*)[ ]*}";
            foreach (Match match in Regex.Matches(data, pattern))
            {
                string eachPattern = "(\\w+[ ]*){((([ ]*\\w+[ ]+)delay([ ]+(\\d)+[ ]*(\\w)+[ ]*;[ ]*)))*}";
                foreach (Match eachMatch in Regex.Matches(match.Value, eachPattern))
                {
                    string[] array = eachMatch.Value.Split(new string[] { " ", "{", "}", ";", "delay" }, StringSplitOptions.RemoveEmptyEntries);
                    ScheduleInfoModel schedule = new ScheduleInfoModel { Name = array[0] };
                    for (int i = 0; i < array.Length / 3; i++) { schedule.SlotInfos.Add(new SlotInfoModel() { Name = array[(3 * i) + 1], Delay = CommonLib.ToInt(array[(3 * i) + 2]) }); }
                    msgInfo.schedules.Add(schedule);
                }
            }
            return true;
        }

4.解析报文消息

       /**********************************************/
        ///<summary>
        ///Name    :AnalysisFrames
        ///Author  :WangHu
        ///Function:***
        ///Version :V1.0.0
        ///Data    :2022.5.20
        ///</summary>
        /**********************************************/
        private static bool AnalysisFrames(List<Message_Type> messages, string data)
        {
            string pattern = "(Frames[ ]*){(([^{}]*{[^{}]*})*)[ ]*}";
            foreach (Match match in Regex.Matches(data, pattern))
            {
                string eachPattern = "(\\w+[ ]*):([ ]*\\w+[ ]*),([ ]*\\w+[ ]*),([ ]*\\d+[ ]*){(([ ]*)|(((([ ]*\\w+[ ]*),([ ]*\\d+[ ]*);[ ]*))+))}";
                foreach (Match eachMatch in Regex.Matches(match.Value, eachPattern))
                {
                    Message_Type message = null;
                    string messagePattern = "(\\w+[ ]*):([ ]*\\w+[ ]*),([ ]*\\w+[ ]*),([ ]*\\d+[ ]*)";
                    foreach (Match messageMatch in Regex.Matches(eachMatch.Value, messagePattern))
                    {
                        string[] array = messageMatch.Value.Split(new string[] { " ", ",", ":" }, StringSplitOptions.RemoveEmptyEntries);
                        uint? id = CommonLib.ToDec(array[1]);
                        if (id == null) { continue; }
                        message = FindMessage(messages, (uint)id);
                        if (message == null)
                        {
                            message = new Message_Type();
                            messages.Add(message);
                        }
                        message.name = CommonLib.ToVar(array[0]);
                        message.id = id;
                        message.transmitter = CommonLib.ToStr(array[2]);
                        message.length = CommonLib.ToInt(array[3]);
                        message.sendType = SendTypeEnum.UF.ToString();
                        message.checksumMode = ChecksumModeEnum.ENHANCED;
                    }
                    string signalPattern = "(\\w+[ ]*),([ ]*\\d+[ ]*);";
                    foreach (Match signalMatch in Regex.Matches(eachMatch.Value, signalPattern))
                    {
                        string[] array = signalMatch.Value.Split(new string[] { " ", ",", ";" }, StringSplitOptions.RemoveEmptyEntries);
                        message.signals.Add(new Signal_Type
                        {
                            name = CommonLib.ToStr(array[0]),
                            startBit = CommonLib.ToInt(array[1]),
                            byteOrder = ByteOrderEnum.INTEL,
                            dataType = DataTypeEnum.UNSIGNED,
                            factor = 1.0,
                            offset = 0.0
                        });
                    }
                }
            }
            return true;
        }

5.解析诊断报文消息

       /**********************************************/
        ///<summary>
        ///Name    :AnalysisDiagnosticFrames
        ///Author  :WangHu
        ///Function:***
        ///Version :V1.0.0
        ///Data    :2022.5.20
        ///</summary>
        /**********************************************/
        private static bool AnalysisDiagnosticFrames(List<Message_Type> messages, string data)
        {
            string pattern = "(Diagnostic_frames[ ]*){(([^{}]*{[^{}]*})*)[ ]*}";
            foreach (Match match in Regex.Matches(data, pattern))
            {
                string eachPattern = "(\\w+[ ]*):([ ]*\\w+[ ]*){((([ ]*\\w+[ ]*),([ ]*\\d+[ ]*);[ ]*)*)}";
                foreach (Match eachMatch in Regex.Matches(match.Value, eachPattern))
                {
                    Message_Type message = null;
                    string messagePattern = "(\\w+[ ]*):([ ]*\\w+)";
                    foreach (Match messageMatch in Regex.Matches(eachMatch.Value, messagePattern))
                    {
                        string[] array = messageMatch.Value.Split(new string[] { " ", ":" }, StringSplitOptions.RemoveEmptyEntries);
                        uint? id = CommonLib.ToDec(array[1]);
                        if (id == null) { continue; }
                        message = FindMessage(messages, (uint)id);
                        if (message == null)
                        {
                            message = new Message_Type();
                            messages.Add(message);
                        }
                        message.name = CommonLib.ToVar(array[0]);
                        message.id = id;
                        message.transmitter = null;
                        message.length = 8;
                        message.sendType = SendTypeEnum.DF.ToString();
                        message.checksumMode = ChecksumModeEnum.CLASSIC;
                    }
                    string signalPattern = "(\\w+[ ]*),([ ]*\\d+[ ]*);";
                    foreach (Match signalMatch in Regex.Matches(eachMatch.Value, signalPattern))
                    {
                        string[] array = signalMatch.Value.Split(new string[] { " ", ",", ";" }, StringSplitOptions.RemoveEmptyEntries);
                        message.signals.Add(new Signal_Type
                        {
                            name = CommonLib.ToStr(array[0]),
                            startBit = CommonLib.ToInt(array[1]),
                            byteOrder = ByteOrderEnum.INTEL,
                            dataType = DataTypeEnum.UNSIGNED,
                            factor = 1.0,
                            offset = 0.0
                        });
                    }
                }
            }
            return true;
        }

6.解析信号信息

       /**********************************************/
        ///<summary>
        ///Name    :AnalysisSignals
        ///Author  :WangHu
        ///Function:***
        ///Version :V1.0.0
        ///Data    :2022.5.20
        ///</summary>
        /**********************************************/
        private static bool AnalysisSignals(List<Message_Type> messages, string data)
        {
            string pattern = "(Signals[ ]*){[^{}]*}";
            foreach (Match match in Regex.Matches(data, pattern))
            {
                string signalPattern = "(\\w+[ ]*):([ ]*\\d+[ ]*),([ ]*([0][x])?\\d+[ ]*),([ ]*\\w+[ ]*(,[ ]*\\w+[ ]*)*);";
                foreach (Match signalMatch in Regex.Matches(match.Value, signalPattern))
                {
                    string[] array = signalMatch.Value.Split(new string[] { " ", ":", ",", ";" }, StringSplitOptions.RemoveEmptyEntries);
                    string signalName = CommonLib.ToStr(array[0]);
                    foreach (Message_Type message in messages)
                    {
                        foreach (Signal_Type signal in message.signals)
                        {
                            if (signal.name == signalName)
                            {
                                signal.length = CommonLib.ToInt(array[1]);
                                signal.initValue = (int?)CommonLib.ToDec(array[2]);
                                for (int i = 0; i < array.Length - 4; i++) { signal.receivers.Add(CommonLib.ToStr(array[i + 4])); }
                            }
                        }
                    }
                }
            }
            return true;
        }

7.解析诊断信号信息

       /**********************************************/
        ///<summary>
        ///Name    :AnalysisDiagnosticSignals
        ///Author  :WangHu
        ///Function:***
        ///Version :V1.0.0
        ///Data    :2022.5.20
        ///</summary>
        /**********************************************/
        private static bool AnalysisDiagnosticSignals(List<Message_Type> messages, string data)
        {
            string pattern = "(Diagnostic_signals[ ]*){[^{}]*}";
            foreach (Match match in Regex.Matches(data, pattern))
            {
                string signalPattern = "(\\w+[ ]*):([ ]*\\d+[ ]*),([ ]*([0][x])?\\d+[ ]*);";
                foreach (Match signalMatch in Regex.Matches(match.Value, signalPattern))
                {
                    string[] array = signalMatch.Value.Split(new string[] { " ", ":", ",", ";" }, StringSplitOptions.RemoveEmptyEntries);
                    string signalName = CommonLib.ToStr(array[0]);
                    foreach (Message_Type message in messages)
                    {
                        foreach (Signal_Type signal in message.signals)
                        {
                            if (signal.name == signalName)
                            {
                                signal.length = CommonLib.ToInt(array[1]);
                                signal.initValue = (int?)CommonLib.ToDec(array[2]);
                            }
                        }
                    }
                }
            }
            return true;
        }

8.解析信号描述关联

       private static bool AnalysisSignalRepresentation(List<Message_Type> messages, string data)
        {
            string pattern = "(Signal_representation[ ]*){[^{}]*}";
            foreach (Match match in Regex.Matches(data, pattern))
            {
                string signalPattern = "([ ]*\\w+[ ]*):([ ]*\\w+[ ]*(,[ ]*\\w+[ ]*)*);";
                foreach (Match signalMatch in Regex.Matches(match.Value, signalPattern))
                {
                    string[] array = signalMatch.Value.Split(new string[] { " ", ",", ":", ";" }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < array.Length - 1; i++)
                    {
                        string signalName = CommonLib.ToStr(array[i + 1]);
                        foreach (Message_Type message in messages)
                        {
                            foreach (Signal_Type signal in message.signals)
                            {
                                if (signal.name == signalName)
                                {
                                    signal.encodingName = CommonLib.ToVar(array[0]);
                                }
                            }
                        }
                    }
                }
            }
            return true;
        }

9.解析描述信息

        /**********************************************/
        ///<summary>
        ///Name    :AnalysisSignalEncodingTypes
        ///Author  :WangHu
        ///Function:***
        ///Version :V1.0.0
        ///Data    :2022.5.20
        ///</summary>
        /**********************************************/
        private static bool AnalysisSignalEncodingTypes(List<Message_Type> messages, string data)
        {
            string pattern = "(Signal_encoding_types[ ]*){(([^{}]*{[^{}]*})*)[ ]*}";
            foreach (Match match in Regex.Matches(data, pattern))
            {
                string eachPattern = "(\\w+[ ]*){((([ ]*physical_value[ ]*),([ ]*\\w+[ ]*),([ ]*\\w+[ ]*),((([ ]+)|)(-?\\d+(\\.\\d+)?)(([ ]+)|)),((([ ]+)|)(-?\\d+(\\.\\d+)?)(([ ]+)|))((,([ ]*)\"((([^\"\\s])|([\\s\\u4e00-\\u9fa5]))*)\")|)[ ]*;)+|[ ]*)((([ ]*logical_value[ ]*),([ ]*\\d+[ ]*),([ ]*\"((([^\"\\s])|([\\s\\u4e00-\\u9fa5]))*)\")[ ]*;[ ]*)+|[ ]*)}";
                foreach (Match eachMatch in Regex.Matches(match.Value, eachPattern))
                {
                    string[] array = eachMatch.Value.Split(new string[] { " ", "{" }, StringSplitOptions.RemoveEmptyEntries);
                    string encodingName = CommonLib.ToVar(array[0]);
                    foreach (Message_Type message in messages)
                    {
                        foreach (Signal_Type signal in message.signals)
                        {
                            if (signal.encodingName == encodingName)
                            {
                                try
                                {
                                    string physicalPattern = "(physical_value[ ]*),([ ]*\\w+[ ]*),([ ]*\\w+[ ]*),((([ ]+)|)(-?\\d+(\\.\\d+)?)(([ ]+)|)),((([ ]+)|)(-?\\d+(\\.\\d+)?)(([ ]+)|))((,([ ]*)\"((([^\"\\s])|([\\s\\u4e00-\\u9fa5]))*)\")|)[ ]*;";
                                    foreach (Match physicalMatch in Regex.Matches(eachMatch.Value, physicalPattern))
                                    {
                                        string[] array1 = physicalMatch.Value.Replace(";", "").Split(new string[] { @"""" }, StringSplitOptions.None);
                                        string[] array2 = array1[0].Split(new string[] { " ", "," }, StringSplitOptions.RemoveEmptyEntries);
                                        signal.minValue = (int?)CommonLib.ToDec(array2[1]);
                                        signal.maxValue = (int?)CommonLib.ToDec(array2[2]);
                                        signal.factor = CommonLib.ToDouble(array2[3]);
                                        signal.offset = CommonLib.ToDouble(array2[4]);
                                        signal.unit = array1.Length >= 2 ? CommonLib.ToStr(array1[1]) : null;
                                    }
                                    string logicalPattern = "(logical_value[ ]*),([ ]*\\d+[ ]*),([ ]*\"((([^\"\\s])|([\\s\\u4e00-\\u9fa5]))*)\")[ ]*;";
                                    foreach (Match logicalMatch in Regex.Matches(eachMatch.Value, logicalPattern))
                                    {
                                        string[] array1 = logicalMatch.Value.Split(new string[] { @"""" }, StringSplitOptions.None);
                                        string[] array2 = array1[0].Split(new string[] { " ", "," }, StringSplitOptions.RemoveEmptyEntries);
                                        signal.valueDescriptions.Add(new ValueDescriptionInfoModel
                                        {
                                            Value = CommonLib.ToDec(array2[1]),
                                            Name = array1[1]
                                        });
                                    }
                                }
                                catch { continue; }
                            }
                        }
                    }
                }
            }
            return true;
        }

五、MatrixCreat工具

这儿我只把链接放上,具体使用说明见后续章节。
LDF转Excel;LDF转位定义;Excel转LDF;Excel转位定义:https://download.youkuaiyun.com/download/weixin_44926112/86912538

六、其他

本文主要是讲解LDF文件的结构和如何解析LDF文件,有些地方可能会有描述性的错误,希望看到的朋友及时指出,我会及时更正错误,其他地方有些借鉴的描述,写此文章的目的是为了交流,非商业用途,欢迎私信讨论,感谢大家阅读。

七、参考

【1】:https://www.jianshu.com/p/8e1e47c4ee36

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值