[英]How to split a string into a List<string> from a multi-line TextBox that adds '\n\r' as line endings?
[英]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 KS
和IS
值,将空/空值转换为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.