繁体   English   中英

如何将多行分隔字符串转换为列表<class></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
 );

从技术上讲,您可以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();

试试这个而不是 Environment.NewLine:

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

你必须拆分多次

一种实现可能如下,但请考虑将其拆分为更多功能,这样可读性更强,并且您可以解析转换后的值。

    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() (指定RegexOptions.Multiline )解析整个多行内容,迭代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值,将空/空值转换为0
根据需要进行调整。


我已经向您的BIRIM class 添加了一个构造函数,它接受与其属性类型匹配的 arguments。
如果您无法修改 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; }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM