为我的tcpdump输出生成正则表达式

时间:2018-02-15 01:16:39

标签: python regex

我有来自TCP转储输出的以下行

09:42:57.346128 IP 192.16.0.1.60800 > 184.84.166.118.49331: Flags [.], seq 62929:65665, ack 0, win 2715, options [nop,nop,TS val 2855068190 ecr 1673141977], length 2736

我有以下python代码从中派生Flag信息。

sentence = "09:42:57.346128 IP 192.16.0.1.60800 > 184.84.166.118.49331: Flags [.], seq 62929:65665, ack 0, win 2715, options [nop,nop,TS val 2855068190 ecr 1673141977], length 2736"
pattern=re.compile(r'Flags\s\[.*\]')
matches=pattern.finditer(sentence )

for match in matches:
    print(match)

,输出

<_sre.SRE_Match object; span=(209, 305), match='Flags [.S], seq 62929:65665, ack 0, win 2715, opt>

你可以看到即使在&#34; Flags [.S]&#34;这是我不想要的。 我认为我的正则表达式&#34; r&#39; Flags \ s [。*]&#39; &#34;表示

  • 标志:开始搜索以&#34; Flags&#34;
  • 开头的字符串
  • \ s:然后是空格
  • [:关注&#34; [&#34;支架标志
  • :下一个字符可以是任何
  • *:next可以是零个或一个字符
  • [:next be&#34;]&#34;

但为什么会超调并提供额外的数据呢? 如果我正常表达像&#34; r&#39; Flags \ s [。*?]&#39; &#34;它返回正确的结果。为什么这样?

3 个答案:

答案 0 :(得分:0)

方括号是re语言中的特殊字符,必须进行转义。它们在第一个例子中被转义,但不在后续行动中。

此外,下一个字符实际上不能是任何:它可以是一个结束方括号。所以,正确的正则表达式是r'Flags\s\[[^\]+]\]'

您可以使用替代语言描述相同的模式。默认情况下,'.*'运算符 greedy :它匹配尽可能多的字符,包括第一个结束方括号,并且仅在最后一个方括号处停止。添加?'.*?')会使其变得非贪婪,并且会在方括号的第一次出现时停止。这就是为什么r'Flags\s[.*?]'有效(但必须是r'Flags\s[.+?]',除非你允许空标志。)

答案 1 :(得分:0)

@DyZ提供了一个很好的答案。但是,至少在Python 2.7.14中,我没有得到你们在使用r'Flags\s[.*?]'时提到的第二个匹配结果

 m = re.search(r'Flags\s\[.*\]', sentence); m.group()
Out[117]: 'Flags [.], seq 62929:65665, ack 0, win 2715, options [nop,nop,TS val 2855068190 ecr 1673141977]'

所以这是第一场比赛,就像你说的那样,比你想要的更匹配。原因是。*匹配任何字符。

但请注意,我必须逃避[],因为[]具有特殊含义。 [any_chars_inside]将与[]中的任意&#34; 1&#34; 匹配。

如果你愿意,有一个例外。特殊字符,如。, ,? (,)失去了意义。所以[。]意味着匹配&#39;。&#39;或&#39; *&#39;文字字符。这就是为什么[.]意味着匹配文字字符&#39;。&#39;,它不在\s之后,所以搜索应该失败。

如果您使用\[ \]转义,则

\[.*\] means match everything that starts with [ and then whatever.

如果您将其更改为\[.*?\],那么如果找到],您就会告诉正则表达式停止。正如@Dyz解释的那样,&#34;?&#34;使搜索变得非贪婪,即不要试图匹配所有内容。

考虑到这一点,@ Dyz的建议r'Flags\s\[[^\]+]\]'将起作用,

r'Flags\s\[.*?\]'

字面意思是,match Flags,然后是a space,然后是[,然后是任意数量的字符,直到您点击]

重新开始你的第一场比赛:

> m = re.search(r'Flags\s\[.*\]', sentence); m.group() Out[117]: 'Flags [.], seq 62929:65665, ack 0, win 2715, options [nop,nop,TS val 2855068190 ecr 1673141977]'

以上是我建议的结果:

> m = re.search(r'Flags\s\[.*?\]', sentence); m.group() Out[118]: 'Flags [.]'

如果你把你所说的工作放进去,我就会失败:

m = re.search(r'Flags\s[.*?]', sentence); m.group() Traceback (most recent call last): File "C:\Python\2.7.12\lib\site-packages\IPython\core\interactiveshell.py", line 2882, in run_code exec(code_obj, self.user_global_ns, self.user_ns) File "<ipython-input-119-fd472f0d5ebb>", line 1, in <module> m = re.search(r'Flags\s[.*?]', sentence); m.group() AttributeError: 'NoneType' object has no attribute 'group'

答案 2 :(得分:0)

  

正则表达式上下文中的重复运算符“*”和“+”本质上是贪婪的。贪婪的运算符将尽可能地匹配字符。

     

例如,我有一个字符串“hello @ world @ from @ my @ house”和一个正则表达式r“。* @”。它将匹配“来自@ my @的hello @ world @”。

     

但是如果添加字符“?”在“”之后,第一场比赛将是“你好@”。 “?”字符使“”运算符变得懒惰,它会尝试将正则表达式与尽可能少的字符匹配。

请随意查看本教程中的正则表达式重复Repetition