Search code examples
c#splitdelimiter

How to convert a multi-line delimited string to a List<class>


I have a string delimited with new line.
I can split it to 4 different list items but I need also split the content of each string, where the items use the | character as separator.

The internal values use Tags like BR=, KS=. I want to use the value of these tags to generate new class objects.
The class is named BIRIM; it has Property names corresponding to the Tags in the strings.

My String:

BR=PALET90|KS=90|IS=1
BR=PALET60|KS=60|IS=1
BR=EUROPALET|KS=55|IS=1
BR=EUROPALET66|KS=66|IS=1
BR=PALET|KS=75|IS=1

My Current Code:

 public class BIRIM {
  public string BR {get;set;}
  public int KS {get;set;}
  public int IS {get;set;}
}

 string birim = node2["BIRIMLER"]?.InnerText;

 string[] birimlerim = birim.Split(
      new[] { Environment.NewLine },
      StringSplitOptions.None
 );

Solution

  • Technically, you can Split several times:

     using System.Linq;
    
     ...
    
     string source = 
       @"BR=PALET90|KS=90|IS=1
         BR=PALET60|KS=60|IS=1
         BR=EUROPALET|KS=55|IS=1
         BR=EUROPALET66|KS=66|IS=1
         BR=PALET|KS=75|IS=1";
    
      ...
    
      var myList = source
        .Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
        .Select(line => line
           .Split('|')
           .Select(item => item.Split('='))
           .ToDictionary(item => item[0].Trim(), item => item[1]))
        .Select(dict => new BIRIM() {
          BR = dict["BR"],
          KS = int.Parse(dict["KS"]),
          IS = int.Parse(dict["IS"])
        })
        .ToList();
    

    However, I suggest implementing TryParse method within BIRIM class, let this class parse for itself when necessary:

    using System.Text.RegularExpressions;
    
    ...
    
    public class BIRIM {
    
      ...
    
      public static bool TryParse(string source, out BIRIM result) {
        result = null;
    
        if (string.IsNullOrWhiteSpace(source))
          return false;
    
        string br = Regex.Match(source, @"BR\s*=\s*(\w+)").Groups[1].Value;
        string KS = Regex.Match(source, @"KS\s*=\s*([0-9]+)").Groups[1].Value;
        string IS = Regex.Match(source, @"IS\s*=\s*([0-9]+)").Groups[1].Value;
    
        if (!string.IsNullOrEmpty(br) && 
             int.TryParse(KS, out int aks) && 
             int.TryParse(IS, out int ais)) {
          result = new BIRIM() {
            BR = br,
            KS = aks,
            IS = ais,
          };
    
          return true;
        }
    
        return false;
      }
    }
    

    Then you can implement the loading as

      var myList = source
        .Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
        .Select(line => BIRIM.TryParse(line, out var value) ? value : null)
        .Where(value => value != null)
        .ToList();