正则表达式是否与右侧匹配?

时间:2016-10-04 08:38:36

标签: regex

我想解析特定的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输出”在技术上是不正确的,我想在可选元素周围显示一些变化。

1 个答案:

答案 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+))?:

请参阅this regex demo