c# - 计算列表中字符串的出现次数并在控制台中显示
问题描述
我现在正在创建一个 Logparser,我可以逐行处理文件夹中的所有文件,并提取我想要的子字符串,即"fct="
. 所有这些使用Regex
,我把结果放在一个List
. 现在我想Count
在我的列表中出现每个字符串并显示它。
我正在使用 GroupBy 但是当我显示结果时,所有的出现都在1
.
实际的:
720 1x
720 1x
710 1x
它应该是:
720 2x
710 1x
我能够发现问题是我逐行读取我的文件,所以如果该"fct="
值不是在同一行上两次,它不会计算它,2
但只计算它1
出现的每一行。
所以我需要找到一种方法来逐行计算我的列表而不是我的文件。
我真的是初学者所以不知道如何做到这一点任何提示将不胜感激。
这是日志数据示例:
<dat>FCT=10019,XN=KEY,CN=ROHWEPJQSKAUMDUC</dat></logurl>
<dat>XN=KEY,CN=RTU FCT=4515</dat>LBZ=test.sqi</logurl>
<dat>XN=KEY,CN=RT</dat>FCT=10019</logurl>
我想显示:
FCT=10019 2x
FCT=4515 1x
我的代码:
class Program
{
static void Main(string[] args)
{
int counter = 0;
string[] dirs = Directory.GetFiles(@"C:/LogParser/LogParserV1", "*.txt");
StreamWriter sw = new StreamWriter("C:/LogParser/LogParserV1/test.txt");
char[] delimiters = { '<', ',', '&', ':', ' ', '\\', '\'' };
string patternfct = "(?<=FCT=)[0-9]*";
foreach (string fileName in dirs)
{
StreamReader sr = new StreamReader(fileName);
{
String lineRead;
while ((lineRead = sr.ReadLine()) != null)
{
//To find all the value of fct= occurence
var listfct = Regex.Matches(lineRead, patternfct,
RegexOptions.IgnoreCase).Cast<Match>().Select(x => x.Value).ToList();
var fctGroups = listfct.GroupBy(i => i);
foreach (var grp in fctGroups)
{
var fct = grp.Key;
var total = grp.Count();
System.Console.WriteLine("fct=" + fct + " " + "Total=" + total);
}
counter++;
}
System.Console.WriteLine(fileName);
sr.Close();
sw.Close();
}
}
// Suspend the screen.
System.Console.ReadLine();
}
}
}
解决方案
您可以尝试在 Linq 的帮助下查询数据:
using System.Linq;
using System.Text.RegularExpressions;
...
Regex regex = new Regex("(?<=FCT=)[0-9]*", RegexOptions.IgnoreCase);
var records = Directory
.EnumerateFiles(@"C:/LogParser/LogParserV1", "*.txt")
.SelectMany(file => File.ReadLines(file))
.SelectMany(line => regex
.Matches(line)
.Cast<Match>()
.Select(match => match.Value))
.GroupBy(number => number)
.Select(group => $"FCT={group.Key} {group.Count()}x");
foreach (string record in records)
Console.WriteLine(record);
演示:我们不能模仿目录和文件,所以我删除了
Directory
.EnumerateFiles(@"C:/LogParser/LogParserV1", "*.txt")
.SelectMany(file => File.ReadLines(file))
但补充说testLines
string[] testLines = new string[] {
"<dat>FCT=10019,XN=KEY,CN=ROHWEPJQSKAUMDUC</dat></logurl>",
"<dat>XN=KEY,CN=RTU FCT=4515</dat>LBZ=test.sqi</logurl>",
"<dat>XN=KEY,CN=RT</dat>FCT=10019</logurl>",
};
Regex regex = new Regex("(?<=FCT=)[0-9]*", RegexOptions.IgnoreCase);
var records = testLines
.SelectMany(line => regex
.Matches(line)
.Cast<Match>()
.Select(match => match.Value))
.GroupBy(number => number)
.Select(group => $"FCT={group.Key} {group.Count()}x");
foreach (string record in records)
Console.WriteLine(record);
结果:
FCT=10019 2x
FCT=4515 1x
编辑:如果要包含file
到records
中,可以使用匿名对象:
var records = Directory
.EnumerateFiles(@"C:/LogParser/LogParserV1", "*.txt")
.SelectMany(file => File
.ReadLines(file)
.Select(line => new {
file = file,
line = line,
}))
.SelectMany(item => regex
.Matches(item.line)
.Cast<Match>()
.Select(match => new {
file = item.file,
number = match.Value
}))
.GroupBy(item => new {
file = item.file,
number = item.number
})
.OrderBy(group => group.Key.file)
.ThenBy(group => group.Key.number)
.Select(group => $"{group.Key.file} has FCT={group.Key.number} {group.Count()}x")
推荐阅读
- html - 我有一个数据表,但不是在操作列上显示两个按钮,而是显示 HTML 代码,所以问题出在哪里
- c++ - return 语句如何在递归中工作?
- asp.net - 能否使用 ITfoxtec SAML 2.0 继续登录 Azure 中的示例项目?
- java - 我无法将图像和字体加载到我的包中(Java)
- sql-server - 使用 Typeorm 连接到 Nestjs 中的 mssql,但 Nest 无法解析 EmployeeRepository 的依赖关系
- java - 一旦范围已经存在,如何显示错误?
- sql - 查询以列格式获取多行数据 - postgresql
- css - CSS如何在垂直线上绘制箭头
- jupyter-notebook - 如何修复:Jupyter PDF 导出 PNG(在降价中)包含失败
- excel-formula - 将列单元格值从一张表复制到另一张表行