我有一些格式的日志字符串:
T01: Warning: Tag1: Message
T23: Tag2: Message2
我正在尝试提取T
号码,检测Warning:
的存在,然后在一个正则表达式中检测标记和消息的文本。 “警告:”的可选要求让我感到沮丧。
private const string RegexExpression = @"^T(?<Number>\d+): (?<Warning>Warning:)? (?<Tag>[^:]+): (?<Message>.*)";
private const string Message = "blar blar blar: some messsage";
//this test works
[TestMethod]
public void RegExMatchByTwoNamedGroupsWarningTest()
{
var rex = new Regex(RegexExpression);
const string wholePacket = "T12: Warning: logtag: " + Message;
var match = rex.Match(wholePacket);
Assert.IsTrue(match.Groups["Warning"].Success); //warning is present
Assert.IsTrue(match.Success);
Assert.IsTrue(match.Groups["Number"].Success);
Assert.AreEqual("12", match.Groups["Number"].Value);
Assert.IsTrue(match.Groups["Tag"].Success);
Assert.AreEqual("logtag", match.Groups["Tag"].Value);
Assert.IsTrue(match.Groups["Message"].Success);
Assert.AreEqual(Message, match.Groups["Message"].Value);
}
[TestMethod]
public void RegExMatchByTwoNamedGroupsNoWarningTest()
{
var rex = new Regex(RegexExpression);
const string wholePacket = "T12: logtag: " + Message;
var match = rex.Match(wholePacket);
Assert.IsFalse(match.Groups["Warning"].Success); //warning is missing
Assert.IsTrue(match.Success); //fails
Assert.IsTrue(match.Groups["Number"].Success); //fails
Assert.AreEqual("12", match.Groups["Number"].Value);
Assert.IsTrue(match.Groups["Tag"].Success); //fails
Assert.AreEqual("logtag", match.Groups["Tag"].Value);
Assert.IsTrue(match.Groups["Message"].Success); //fails
Assert.AreEqual(Message, match.Groups["Message"].Value);
}
答案 0 :(得分:1)
尝试设置RegexOptions.IgnorePatternWhitespace
:
var rex = new Regex(RegexExpression, RegexOptions.IgnorePatternWhitespace);
或者,更新正则表达式模式:
private const string RegexExpression = @"^T(?<Number>\d+):\s*(?<Warning>Warning:)?\s*(?<Tag>[^:]+):\s*(?<Message>.*)";
答案 1 :(得分:1)
你的问题是你的正则表达式中的空白。
如果警告组不存在,那么它会尝试匹配可选警告模式之前的空间和之后的空格。显然,你只想匹配其中一个。
解决方案是在可选模式中包含一个空格以及警告。即:
^T(?<Number>\d+): (?<Warning>Warning: )?(?<Tag>[^:]+): (?<Message>.*)
答案 2 :(得分:1)
@"^T(?<Number>\d+): ((?<Warning>Warning:.*) )?(?<Tag>[^:]+): (?<Message>.*)$";
我不确定行尾(Dollar)的标志,因为我不熟悉c#,但是......
答案 3 :(得分:1)
这个正则表达式考虑空间并尽力而为!
@"^T(?'Number'\d+)\s*:\s*((?'Warning'\bWarning\b)\s*:)?\s*(?'Tag'.*?Tag.*?):\s*(?'Message'.*?)$"
将此正则表达式与RegexOptions.IgnoreCase