如何将多行分隔字符串转换为列表<class>

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

我有一个用新行分隔的字符串。
我可以将它拆分为 4 个不同的列表项,但我还需要拆分每个字符串的内容,其中项目使用 | 字符作为分隔符。

内部值使用 标签,如 BR=KS=。 我想使用这些 标签的值 来生成新的 class 对象。
class 被命名为 BIRIM;它有 属性 个名称对应于字符串中的 标签

我的字符串:

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

我的当前代码:

 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
 );

试试这个而不是 Environment.NewLine :

 string[] birimlerim = birim.Split(new string[] { "\r\n" }, StringSplitOptions.None);

从技术上讲,您可以 Split 多次 次:

 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();

但是,我建议在 BIRIM class 中实现 TryParse 方法,必要时让这个 class 自己解析 :

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;
  }
}

然后你可以实现加载为

  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();

你要拆分多次

一个实现可能是下面这样,但是请考虑拆分成更多的函数,它会更易读,你可以解析转换后的值。

    private static List<BIRIM> ParseBirim(string birimText)
    {
        var birims = new List<BIRIM>();

        string[] birimlerim = birimText.Trim().Split(Environment.NewLine);

        foreach (string birim in birimlerim)
        {
            string[] bki = birim.Split('|');

            birims.Add(new BIRIM
            {
                BR = bki[0].Split('=')[1],
                KS = Convert.ToInt32(bki[1].Split('=')[1]),
                IS = Convert.ToInt32(bki[2].Split('=')[1]),
            });
        }

        return birims;
    }

另一种选择。
使用 Regex.Matches() (specifying RegexOptions.Multiline), iterate the MatchCollection 项解析整个多行内容,以构建具有提取值的新 BIRIM 对象。

string pattern = @"^BR=(?<br>.*?)\|KS=(?<ks>.*?)\|IS=(?<is>.*?)$";
string innerText = node2["BIRIMLER"]?.InnerText;

var birims = Regex.Matches(innerText, pattern, RegexOptions.Multiline)
    .OfType<Match>().Select(m => 
        new BIRIM(
            m.Groups["br"].Value,
            int.Parse('0' + m.Groups["ks"].Value.Trim()),
            int.Parse('0' + m.Groups["is"].Value.Trim())))
    .ToList();

这处理 null KSIS 值,将 empty/null 值转换为 0.
根据需要进行调整。


我已经向您的 BIRIM class 添加了一个构造函数,它接受与其属性类型相匹配的参数。
如果无法修改 class 结构,请使用语法 (new T() { PropertyName = PropertyValue }):

public class BIRIM
{
    public BIRIM(string sbr, int sks, int sis) {
        BR = sbr; KS = sks; IS = sis;
    }

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