为重复行的特定实例解析分隔的数据
本文关键字:分隔 数据 实例 | 更新日期: 2023-09-27 18:07:17
我有一个格式如下的字符串数组,其中每个字符串以一系列三个字符开头,表示它包含的数据类型。例如:
ABC |…DEF |…
RHG | 1……
RHG | 2……RHG | 3……
XDF |…
我想找到任何重复的行(在这个例子中是RHG),并用一个特殊字符标记最后一行:
> RHG | 3 .........
最好的方法是什么?我目前的解决方案有一个方法来计算行标题,并创建一个包含标题计数的字典。
protected Dictionary<string, int> CountHeaders(string[] lines)
{
Dictionary<string, int> headerCounts = new Dictionary<string, int>();
for (int i = 0; i < lines.Length; i++)
{
string s = lines[i].Substring(0, 3);
int value;
if (headerCounts.TryGetValue(s, out value))
headerCounts[s]++;
else
headerCounts.Add(s, 1);
}
return headerCounts;
}
在主解析方法中,我选择重复的行。
var repeats = CountHeaders(lines).Where(x => x.Value > 1).Select(x => x.Key);
foreach (string s in repeats)
{
// Get last instance of line in lines and mark it
}
这是我所能做到的。我想我可以做我想要的另一个LINQ查询,但我不太确定。而且,我忍不住觉得有一个更优的解决方案。
您可以使用LINQ来实现。
输入字符串:
var input = @"ABC|.....
DEF|...
RHG|1........
RHG|2........
RHG|3........
XDF|......";
LINQ
:
var results = input.Split(new[] { Environment.NewLine })
.GroupBy(x => x.Substring(0, 3))
.Select(g => g.ToList())
.SelectMany(g => g.Count > 1 ? g.Take(g.Count - 1).Concat(new[] { string.Format(">{0}", g[g.Count - 1]) }) : g)
.ToArray();
我使用Select(g => g.ToList())
投影使g.Count
O(1)在后面的查询步骤中运算。
您可以使用String.Join
方法将Join
结果数组转换为一个字符串:
var output = String.Join(Environment.NewLine, results);
或者,您可以使用反向引用regex查找重复行。我使用您的示例数据编写了这个hack regex,它匹配以前面的'tag'开头的行,管道分隔值。
^(?<Tag>.+)[|].+['n'r]('k<Tag>[|].+['n'r])+
匹配范围从第一个RHG行开始一直到最后一个RHG行
下面是一个在Linq语句中包含解析和计数的示例—如果您愿意,可以随意拆分它:
string[] data = new string[]
{
"ABC|.....",
"DEF|...",
"RHG|1........",
"RHG|2........",
"RHG|3........",
"XDF|......"
};
data.Select(d=> d.Split('|')) // split the strings
.Select(d=> new { Key = d[0], Value = d[1] }) // select the key and value
.GroupBy (d => d.Key) // group by the key
.Where(g=>g.Count() > 1 ) // find duplicates
.Select(d => d.Skip(1)) // select the repeating elements
.SelectMany(g=>g) // flatten into a single list
;
这将给你一个重复的键/值对列表。对于样本数据它将返回
Key Value
RHG 2........
RHG 3........
我不确定你所说的"标记"行是什么意思,但是…