可选匹配多个字符串

时间:2014-09-08 20:43:02

标签: c# regex

所以我有以下字符串:

192.168.1.254... 0000 0000 0010 = Flags: 0x002 (SYN)445
192.168.1.254... 0000 0000 0010 = Flags: 0x002 (SYN,ACK)445
192.168.1.254... 0000 0000 0010 = Flags: 0x002 (SYN,ACK,PSH)445

我正在尝试创建一个匹配所有这些字符串的正则表达式,我试图将某些内容分开。我目前创建了以下正则表达式。

Regex pattern = new Regex(@"(?<ip>(?:\d{1,3}\.){3}\d{1,3}).*Flags:\s\d{1}x\d{3}\s\((?<flag>\w+)\)(?<port>\d+)");

这给了我ip = 192.168.1.254,flag = SYN和port = 445。 但是这只会匹配第一个字符串。我希望标记部分包含SYN - SYN,ACK - SYN,ACK,PSH,甚至可能包含SYN,ACK,PSH,URG等第四部分。

我已经尝试过查看可选的正则表达式(但无法使其工作),例如:

Regex pattern = new Regex(@"(?<ip>(?:\d{1,3}\.){3}\d{1,3}).*Flags:\s\d{1}x\d{3}\s\((?<flag>[\w,]+)\)(?<port>\d+)");

或创建多个正则表达式以单独匹配每个正则表达式(这会阻碍程序的其余部分)。

我认为使ACK,PSH部分可选,但我无法使其工作。

3 个答案:

答案 0 :(得分:0)

使用this awesome regex tester,我找到了

((?:\ d {1,3}。){4})..(?:(?:\ d){4}){3} =标志:\ dx \ d {3}(( ?:(\ W {3}),)+)(\ d +)

满足您的需求。请务必使用Multiline选项并使用.Matches成员。

答案 1 :(得分:0)

你的第一个正则表达式很接近。问题在于flag群组:\w+匹配SYN,但它会在SYN,ACKSYN,ACK,PSH的逗号处中断。

您可以通过添加包含逗号的可选的未捕获组来解决此问题,如下所示:

                                                                changes
                                                               vvvvvvvvv
(?<ip>(?:\d{1,3}\.){3}\d{1,3}).*Flags:\s\dx\d{3}\s\((?<flag>\w+(?>,\w+)*)\)(?<port>\d+) 

答案 2 :(得分:0)

您可以替换它。

(?<flag>\w+)

使用

((?<flag>\w+),?)+

解释

(?<flag>\w+) -> take word
,?           -> optional comma
()+          -> at least 1 flag

当您使用Matches时,您将获得3场比赛并拿走所有旗帜,您可以使用Captures

var regexPattern = @"(?<ip>(?:\d{1,3}\.){3}\d{1,3}).*Flags:\s\d{1}x\d{3}\s\(((?<flag>\w+),?)+\)(?<port>\d+)";
var pattern = new Regex(regexPattern);
var matches = pattern.Matches(input);
foreach (Match match in matches)
{
    var ip = match.Groups["ip"].Value;
    var port = match.Groups["port"].Value;
    var flags = match.Groups["flag"].Captures
        .Cast<Capture>()
        .Select(c => c.Value)
        .ToArray();        
}