我正在尝试使用正则表达式读取日志文件并提取一些机器/设置信息。以下是日志中的示例:
...
COMPUTER INFO:
Computer Name: TESTCMP02
Windows User Name: testUser99
Time Since Last Reboot: 405 Minutes
Processor: (2 processors) Intel(R) Xeon(R) CPU 5160 @ 3.00GHz
OS Version: 5.1 .number 2600:Service Pack 2
Memory: RAM: 48% used, 3069.6 MB total, 1567.3 MB free
ServerTimeOffSet: -146 Seconds
Use Local Time for Log: True
INITIAL SETTINGS:
Command Line: /SKIPUPDATES
Remote Online: True
INI File: c:\demoapp\system\DEMOAPP.INI
DatabaseName: testdb
SQL Server: 10.254.58.1
SQL UserName: SQLUser
ODBC Source: TestODBC
Dynamic ODBC (not defined): True
...
我想捕获每个“块”数据,使用标题作为一个组,数据作为第二个(即“计算机信息”,“计算机名称:.......”)并重复每个块都有这个。到目前为止的表达式是
(?s)(\p{Lu}{1,} \p{Lu}{1,}:\r\n)(.*\r\n\r\n)
这会将块拉出到它应该的组中,这很棒。但我需要让它重复捕获,这似乎是我无法得到的。我尝试了几种分组表达式,包括:
(?s)(?:(\p{Lu}{1,} \p{Lu}{1,}:\r\n)(.*\r\n\r\n))*
这似乎是正确的,但我得到了很多带有空组项值的NULL结果组。我正在使用.Net RegEx类来应用表达式,任何人都可以帮助我吗?
答案 0 :(得分:12)
重复小组是不可能的。该组将包含最后一场比赛。
你需要把它分成两个问题。首先,找到每个部分:
new Regex(@"(?>^[A-Z\s]+:\s*$)\s*(?:(?!^\S).)*", RegexOptions.Singleline | RegexOptions.Multiline);
然后,在每个匹配中,使用另一个正则表达式将每个字段/值匹配到组中:
new Regex(@"^\s+(?<name>[^:]*):\s*(?<value>.*)$", RegexOptions.Multiline);
使用它的代码如下所示:
Regex sectionRegex = new Regex(@"(?>^[A-Z\s]+:\s*$)\s*(?:(?!^\S).)*", RegexOptions.Singleline | RegexOptions.Multiline);
Regex nameValueRegex = new Regex(@"^\s+(?<name>[^:]*):\s*(?<value>.*)$", RegexOptions.Multiline);
MatchCollection sections = sectionRegex.Matches(logData);
foreach (Match section in sections)
{
MatchCollection nameValues = nameValueRegex.Matches(section.ToString());
foreach (Match nameValue in nameValues)
{
string name = nameValue.Groups["name"].Value;
string value = nameValue.Groups["value"].Value;
// OK, do something here.
}
}
答案 1 :(得分:1)
((?<header>[^:]+:)(?<content>[^\r\n]+)?\r\n)+
或者,如果项目之间有空行:
(((?<header>[^:]+:)(?<content>[^\r\n]+)?\r\n)|\r\n)+
答案 2 :(得分:1)
以下是我将如何进行的。这将允许您轻松获取特定组的值,但表达式会更复杂一些。我添加换行符以便于阅读。这是开始:
COMPUTER INFO:.*Computer Name:\s*(?<ComputerName>[\w\s]+).*Windows User Name:\s*(?<WindowUserName>[\w\s]+).*Time Since Last Reboot:\s*(?<TimeSinceLastReboot>[\w\s]+).* (?# This continues on through each of the lines... )
使用Comiled,IgnoreCase,SingleLine和CultureInvariant
然后你可以通过ex:
组来匹配这个string computerName = match.Group["ComputerName"].Value;
string windowUserName = match.Group["WindowUserName"].Value;
// etc.
答案 3 :(得分:1)