我该如何修复这个正则表达式? (nmap 结果)

How can I fix this regex? (nmap results)

我正在尝试将文本解析为 4 个捕获组,但我 运行 遇到了问题。

我的正则表达式是:

(\d{1,5})\/(tcp|udp)\s+open\s+(\S+)\s*(.*)?

一些样本输入是:

Nmap scan report for X
Host is up (0.097s latency).
Not shown: 192 closed ports
PORT     STATE         SERVICE       VERSION
135/udp  open          msrpc
137/udp  open          netbios-ns    Microsoft Windows XP netbios-ssn (workgroup: THINC)
135/tcp open  msrpc        Microsoft Windows RPC
139/tcp open  netbios-ssn  Microsoft Windows netbios-ssn
445/tcp open  microsoft-ds Windows XP microsoft-ds

这几乎完美。问题出在 135/udp 的线上,没有版本字段,所以我的那条线的捕获组 4 环绕并抓住了整个下一行(从 137/udp 开始)。

对于 135/udp 的行(或版本字段为空的任何地方),我希望捕获组 4 为空/null。

我的最后一个 .* 似乎不应超过行终止符,但确实如此。我还在我的最后一个捕获组之后包含了 ? 以尝试使其成为可选的,例如允许空值。

谁能指出我做错了什么?解释我的错误比只提供一个有效的正则表达式更有帮助。

Visual representation

\s 似乎匹配换行符。这对我来说是出乎意料的——我本以为 \s 只匹配白色 space。

尝试只匹配制表符和 spaces: [ \t] 而不是 \s.

并且要求更高 - 意味着设置 spaces 和非 spaces +,而不是 *:

(\d{1,5})\/(tcp|udp)[ \t]+open[ \t]+(\S+)[ \t]+(.*)

(\S+) 是打开 space 后预期的一个条目。 但是因为我们只对在那之后继续的那些行感兴趣: [ \t]+ 要求在该条目之后有 space(不包括在那里结束的行)- (.*) 捕获 space.

之后的所有内容

正如 bytepusher 所指出的,我有一个匹配换行符的 \s。我将 \s 替换为空格或制表符 [\t] 的显式匹配,如:

(\d{1,5})\/(tcp|udp)\s+open\s+(\S+)[ \t]*(.*)?

最正确的是,我将 /s 的所有实例替换为预期间距字符的显式匹配:

(\d{1,5})\/(tcp|udp)[ \t]+open[ \t]+(\S+)[ \t]*(.*)?