可选匹配多个字符串

本文关键字:字符串 | 更新日期: 2023-09-27 18:21:10

所以我有以下字符串:

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,它将匹配所有这些字符串,并且我正在尝试分离某些内容。我目前已经创建了以下Regex。

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部分是可选的,但我无法让它发挥作用。

可选匹配多个字符串

使用这个很棒的regex测试仪,我发现

((?:''d{1,3}.){4})(''d+)

符合您的需求。请确保使用"多行"选项并使用.Matches成员。

您的第一个正则表达式已关闭。问题出在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+) 

您可以替换它。

(?<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();        
}