简体   繁体   English

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

[英]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 |我可以将它拆分为 4 个不同的列表项,但我还需要拆分每个字符串的内容,其中项目使用| character as separator.字符作为分隔符。

The internal values use Tags like BR= , KS= .内部值使用诸如BR=KS=之类的标签 I want to use the value of these tags to generate new class objects.我想使用这些标签的值生成新的 class 对象。
The class is named BIRIM ; class 名为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
 );

Technically, you can Split several times:从技术上讲,您可以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();

However, I suggest implementing TryParse method within BIRIM class, let this class parse for itself when necessary:但是,我建议在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;
  }
}

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

try this instead of Environment.NewLine:试试这个而不是 Environment.NewLine:

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

You have to split multiple times你必须拆分多次

One implementation could be the following, but please consider to split it in more functions, it will be more readable and you can parse converted value.一种实现可能如下,但请考虑将其拆分为更多功能,这样可读性更强,并且您可以解析转换后的值。

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

Another option.另外一个选择。
Parse the whole multi-line content using Regex.Matches() (specifying RegexOptions.Multiline ), iterate the MatchCollection items to build new BIRIM objects with the values extracted.使用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();

This handles null KS and IS values, converting to empty/null values to 0 .这处理 null KSIS值,将空/空值转换为0
Adapt as needed.根据需要进行调整。


I've added a Constructor to your BIRIM class that accepts arguments that match the Type of its Properties.我已经向您的BIRIM class 添加了一个构造函数,它接受与其属性类型匹配的 arguments。
If you cannot modify the class structure, use the syntax ( new T() { PropertyName = PropertyValue } ):如果您无法修改 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