Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String parsing techniques

I am trying to find a good way to parse a message string into an object. The string is of fixed length and described below.

Snippet of string spec

  • protocol = int(2)
  • message type = string(1)
  • measurement = string(4)
  • etc

Doing a simple String.Split will work, but I think may be a bit cumbersome when you start to get towards the end of the string. e.g.:

var field1 = s.SubString(0,2);
var field2 = s.SubString(2,4);
....
var field99 = s.SubString(88,4); // difficult magic numbers

I considered using a Regex and thought that maybe even more confusing.

I was trying to think of an elegant solution, where I could create a Parser which was passed a 'config' that would detail how to parse the string.

Something like...

 MyConfig config = new MyConfig()
 config.Add("Protocol",    Length=2, typeof(int));
 config.Add("MessageType", Length=1, typeof(char));


 Parser p = new Parser(config);
 var parserResult = p.Parse(message);

...but I'm going around in circles at the minute and not getting anywhere. Any pointers would be a great help.

like image 767
Matt Avatar asked Aug 10 '26 14:08

Matt


1 Answers

So a simple message structure:

class Message
{
    public DateTime DateTime { get; set; }
    public int Protocol { get; set; }
    public string Measurement { get; set; }
    public string Type { get; set; }
    //....
}

Combined with a class that knows how to deserialize it:

class MessageSerializer
{
    public Message Deserialize(string str)
    {
        Message message = new Message();
        int index = 0;
        message.Protocol = DeserializeProperty(str, ref index, 2, Convert.ToInt32);
        message.Type = DeserializeProperty(str, ref index, 1, Convert.ToString);
        message.Measurement = DeserializeProperty(str, ref index, 4, Convert.ToString);
        message.DateTime = DeserializeProperty<DateTime>(str, ref index, 16, (s) =>
        {
            // Parse date time from 2013120310:28:55 format
            return DateTime.ParseExact(s, "yyyyMMddhh:mm:ss", CultureInfo.CurrentCulture);
        });
        //...
        return message;
    }

    static T DeserializeProperty<T>(string str, ref int index, int count, 
        Func<string, T> converter)
    {
        T property = converter(str.Substring(index, count));
        index += count;
        return property;
    }
}
like image 120
TVOHM Avatar answered Aug 12 '26 08:08

TVOHM



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!