正则表达式与组中的行结束

时间:2015-06-05 13:26:55

标签: python regex

鉴于此类意见:

.-[ 127.0.0.1/44963 -> 127.0.0.1/502 (syn+ack) ]-
|
| server   = 127.0.0.1/502
| os       = ???
| dist     = 0
| params   = none
| raw_sig  = 4:64+0:0:0:32768,0:::0
|
`----

.-[ 127.0.0.1/44963 -> 127.0.0.1/502 (syn+ack) ]-
|
| server   = 127.0.0.1/502
| os       = ???
| dist     = 0
| params   = none
| raw_sig  = 4:64+0:0:0:32768,0:::0
|
`----
...

我正在尝试使用正则表达式来获取输出中所有os的值(将有数百个)。

我试过这个:

import os, subprocess, re

dir = '/home/user/Documents/ics-passif-asset-enumeration/pcap/'

for filename in os.listdir(dir):
    inp = '...'
    match = re.match( r'(.*)os(.*)\n(.*)', inp  )
    print match.group(1)

但匹配是NoneType。从来没有真正使用正则表达式,我有点迷失。

编辑:

预期输出是所有os值的列表。在这种情况下,它将是:

???
???

6 个答案:

答案 0 :(得分:2)

我希望这就是你要找的东西

>>> import re
>>> string = """.-[ 127.0.0.1/44963 -> 127.0.0.1/502 (syn+ack) ]-
... |
... | server   = 127.0.0.1/502
... | os       = ???
... | dist     = 0
... | params   = none
... | raw_sig  = 4:64+0:0:0:32768,0:::0
... |
... `----"""
>>> match = re.match( r'(.*)os\s*=(.*?)\n', string, re.DOTALL)
>>> match.group(2)
' ???'

所做的更改

  • re.DOTALL此标志是必需的,以便您尝试匹配多行输入。

  • os\s*=(.*?)

    • \s*= =和空格由捕获组组成,因为我们对它们不感兴趣。

    • (.*?) ?使其非贪婪,以便匹配到第一行结束

  • match.group(2)这是第二个匹配组,而不是第一个。

更好更短的解决方案

您可以使用re.findall()使用更简洁的正则表达式

os\s*=(.*)

<强>测试

>>> string = """.-[ 127.0.0.1/44963 -> 127.0.0.1/502 (syn+ack) ]-
... |
... | server   = 127.0.0.1/502
... | os       = ???
... | dist     = 0
... | params   = none
... | raw_sig  = 4:64+0:0:0:32768,0:::0
... |
... `----
... 
... .-[ 127.0.0.1/44963 -> 127.0.0.1/502 (syn+ack) ]-
... |
... | server   = 127.0.0.1/502
... | os       = ???
... | dist     = 0
... | params   = none
... | raw_sig  = 4:64+0:0:0:32768,0:::0
... |
... `----
... ..."""

>>> re.findall(r"os\s*=(.*)", string)
[' ???', ' ???']

答案 1 :(得分:2)

re.findall会返回一系列结果!太棒了!假设您的输入格式非常一致,这应该像魅力一样:

>>> inp = '''
... .-[ 127.0.0.1/44963 -> 127.0.0.1/502 (syn+ack) ]-
... |
... | server   = 127.0.0.1/502
... | os       = ???
... | dist     = 0
... | params   = none
... | raw_sig  = 4:64+0:0:0:32768,0:::0
... |
... `----
... 
... .-[ 127.0.0.1/44963 -> 127.0.0.1/502 (syn+ack) ]-
... |
... | server   = 127.0.0.1/502
... | os       = ???
... | dist     = 0
... | params   = none
... | raw_sig  = 4:64+0:0:0:32768,0:::0
... |
... `----
... ...
... '''
>>> re.findall(r'^| os\s+= (.*)$', inp, flags=re.MULTILINE)
['???', '???']

我同意这样的想法,即格式应该严格,以确保字符串不会出现在其他地方。如果这一切都来自一个剧本,那么严格不应该是一个问题(你希望)。如果是通过人工输入......我会感到惊讶。

答案 2 :(得分:0)

要使点运算符(。)匹配换行符,请在匹配调用中添加一个标志:

match = re.match( r'(.*)os(.*)\n(.*)', inp, flags=re.DOTALL  )

答案 3 :(得分:0)

如果我理解你所希望的(并且假设你的输入是你在这里复制的(多行,多行),这个正则表达式应该用修饰符gm来匹配所有并且让^和$匹配分别开始和结束行:

^|\s*os\s*=\s*(.*)$

演示Here

答案 4 :(得分:0)

您可以尝试使用findall()方法:

for filename in os.listdir(dir):
    inp = '...'
    match = re.findall('os(.*)\n', inp)
    print match

答案 5 :(得分:0)

正如@Tensibai所说,你可能最好使用^$来匹配行的开头和结尾,以及一个非常具体的模式(如他给出的那样)来制作确定字符串&#34; os&#34;在其他地方不匹配,例如在主机名中。

直接找到所有匹配的&#34; os =&#34;使用re.findall( r'^|\s*os\s*=\s*(.*)$', inp, re.MULTILINE ),返回匹配的os值列表。