如何从日志文件提取"Running module"后的模块名并存入数组?
如何从日志中提取“Running module”后的模块名并存入数组?
我来帮你搞定这个问题!你的目标是从日志文本里提取Running module之后、以句号结尾的模块名(比如示例里的SamplesSim),但当前代码只输出了Run,这是因为字符串截取的逻辑出了问题。先来看下你的日志示例:
25.5.2018 10:42:35.621 Status message 0884:Running module SamplesSim.
25.5.2018 10:42:35.621 Status message 0120:Data Input: Opening: T:\RCS\BiggieStatementsOn\PRINT\INPUTJACK\FCA_HomeBandAccounts_23052018.csv. (DataInput1)
你之前的代码里,lastIndex = startIndex +3这一步完全不符合需求——它只是从Running module的起始位置截取3个字符,自然会得到Run。下面给你两种可靠的解决方案:
方法1:用正则表达式(最推荐)
正则表达式是日志解析的绝佳工具,能精准匹配我们需要的内容,还能一次性提取所有符合条件的模块名:
using System; using System.Text.RegularExpressions; using System.Collections.Generic; class LogParser { static void Main() { string consoleOutput = compiler.StandardOutput.ReadToEnd(); // 正则规则:匹配"Running module "后到"."前的所有非句号字符 string regexPattern = @"Running module ([^.]+)\."; MatchCollection matches = Regex.Matches(consoleOutput, regexPattern); List<string> moduleList = new List<string>(); foreach (Match match in matches) { if (match.Success) { // 分组1就是我们要的模块名 moduleList.Add(match.Groups[1].Value.Trim()); } } // 转成数组供后续调用 string[] ModuleParams = moduleList.ToArray(); // 测试输出 foreach (string module in ModuleParams) { Console.WriteLine($"提取到的模块:{module}"); } } }
解释
([^.]+):匹配除了句号之外的任意字符,确保我们拿到的是Running module和结尾句号之间的完整模块名(如果模块名包含特殊字符也能兼容)Regex.Matches:会找出日志中所有符合规则的模块名,而不只是第一个
方法2:修正你的IndexOf逻辑
如果你不想用正则,可以调整字符串定位的逻辑,精准找到模块名的起止位置:
using System; using System.Collections.Generic; class LogParser { static void Main() { string consoleOutput = compiler.StandardOutput.ReadToEnd(); int startMarkerIndex = consoleOutput.IndexOf("Running module"); List<string> moduleList = new List<string>(); // 循环处理,提取所有符合条件的模块名 while (startMarkerIndex != -1) { // 定位到模块名的起始位置:跳过"Running module "这段文本 int moduleStart = startMarkerIndex + "Running module ".Length; // 从模块名起始位置开始找第一个句号的位置 int moduleEnd = consoleOutput.IndexOf('.', moduleStart); if (moduleEnd != -1) { // 截取模块名并去除可能的空格 string moduleName = consoleOutput.Substring(moduleStart, moduleEnd - moduleStart).Trim(); moduleList.Add(moduleName); } // 继续查找下一个"Running module"的位置,避免重复提取 startMarkerIndex = consoleOutput.IndexOf("Running module", moduleEnd); } // 转成数组 string[] ModuleParams = moduleList.ToArray(); // 测试输出 foreach (string mod in ModuleParams) { Console.WriteLine(mod); } } }
解释
- 先找到
Running module的位置,然后跳过这段文本的长度,定位到模块名的开头 - 再从这个位置往后找第一个句号,中间的内容就是我们要的模块名
- 用循环可以处理日志中所有的匹配项,而不是只提取第一个
内容的提问来源于stack exchange,提问作者YongaJ
相关产品推荐
相关产品推荐

