我有来自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; r&#39; Flags \ s [。*?]&#39; &#34;它返回正确的结果。为什么这样?
答案 0 :(得分:0)
方括号是re
语言中的特殊字符,必须进行转义。它们在第一个例子中被转义,但不在后续行动中。
此外,下一个字符实际上不能是任何:它可以是但一个结束方括号。所以,正确的正则表达式是r'Flags\s\[[^\]+]\]'
。
您可以使用替代语言描述相同的模式。默认情况下,'.*'
运算符 greedy :它匹配尽可能多的字符,包括第一个结束方括号,并且仅在最后一个方括号处停止。添加?
('.*?'
)会使其变得非贪婪,并且会在方括号的第一次出现时停止。这就是为什么r'Flags\s[.*?]'
有效(但必须是r'Flags\s[.+?]'
,除非你允许空标志。)
答案 1 :(得分:0)
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。