我想解析特定的tcpdump
模式,并使用optional matches来考虑一些可选部分(regex101 demo):
10:14:48.983541 IP 10.242.136.232.34266 > 10.81.163.129.9200: Flags [S], seq 2294574211, win 29200, options [mss 1460,sackOK,TS val 22536912 ecr 0,nop,wscale 7], length 0
10:14:48.983541 IP 10.242.136.232 > 10.81.163.129.9200: fictional stuff
10:14:48.983541 IP 10.242.136.232 > 10.81.163.129: also fictional stuff
字符串的一般结构是“东西,IP地址,可选端口,>符号,IP,可选端口,冒号,某些”,由空格分隔。我的匹配模式是
.+(?P<src_ip>\d*\.\d*\.\d*\.\d*)(?:\.(?P<src_port>\d*))?.>.(?P<dst_ip>\d*\.\d*\.\d*\.\d*)(?:\.(?P<dst_port>\d*))?:\.*
在上面的演示正则表达式中,似乎匹配是从右边完成的(大部分都是正确的)但是然后在前往左边的路上和IP的第一个八位字节(第一个\d*
中发生了一些事情。模式)永远不会匹配。的为什么吗
注意:最后两个“tcpdump输出”在技术上是不正确的,我想在可选元素周围显示一些变化。
答案 0 :(得分:0)
我看到几个潜在的“瓶颈”,主要问题是第一个贪婪的.+
。该子模式首先抓取整个字符串,并通过尝试容纳后续模式的文本来开始回溯。因此,它使数字“从右边”匹配。将它转换为惰性.+?
将使正则表达式跳过子模式并首先尝试后续子模式,并且只有在不匹配时,惰性.+?
才会“扩展”,并且数字将从右。
使其工作的另一种方法是在这些数字之前指定唯一的上下文,这里是一个空格。只需在贪婪的.+
之后添加一个空格,并且回溯将抓住一个或多个字符,直到最后一个空格跟随其余的子模式。请参阅this regex demo。
此外,最后\.*
不是必需的,您可以将其删除。您似乎想要在所有情况下匹配1位或更多位数,因此,您可以将所有\d*
替换为\d+
。如果>
附有空格,请将.>.
替换为\s*>\s*
。
我建议:
.+?(?P<src_ip>\d+\.\d+\.\d+\.\d+)(?:\.(?P<src_port>\d+))?\s*>\s*(?P<dst_ip>\d+\.\d+\.\d+\.\d+)(?:\.(?P<dst_port>\d+))?:
或带有限制量词的bit contracted version:
.+?(?P<src_ip>\d+(?:\.\d+){3})(?:\.(?P<src_port>\d+))?\s*>\s*(?P<dst_ip>\d+(?:\.\d+){3})(?:\.(?P<dst_port>\d+))?: