3

我有一些格式的日志字符串:

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);
    }
4

4 回答 4

1

尝试设置RegexOptions.IgnorePatternWhitespace

var rex = new Regex(RegexExpression, RegexOptions.IgnorePatternWhitespace);

或者,更新正则表达式模式:

private const string RegexExpression = @"^T(?<Number>\d+):\s*(?<Warning>Warning:)?\s*(?<Tag>[^:]+):\s*(?<Message>.*)";
于 2012-08-22T16:12:11.253 回答
1

你的问题是你的正则表达式中的空格。

如果警告组不存在,那么它会尝试匹配可选警告模式之前的空格和之后的空格。显然,您只想匹配其中之一。

解决方案是在可选模式中包含一个空格以及警告。IE:

^T(?<Number>\d+): (?<Warning>Warning: )?(?<Tag>[^:]+): (?<Message>.*)
于 2012-08-22T16:18:59.357 回答
1
@"^T(?<Number>\d+): ((?<Warning>Warning:.*) )?(?<Tag>[^:]+): (?<Message>.*)$";

我不确定行尾(美元)符号,因为我不熟悉 c#,但是......

于 2012-08-22T16:20:02.987 回答
1

此正则表达式考虑空间并尽力而为!

@"^T(?'Number'\d+)\s*:\s*((?'Warning'\bWarning\b)\s*:)?\s*(?'Tag'.*?Tag.*?):\s*(?'Message'.*?)$"

将此正则表达式与RegexOptions.IgnoreCase

于 2012-08-22T17:08:53.860 回答