【发布时间】:2019-12-22 03:55:45
【问题描述】:
概述
我正在尝试从文件中获取信息(逐行读取),使用正则表达式将数据拆分为字典字典(嵌套字典),其中格式为
{
IP1: {
Message1 {count},
Message2 {count},
Message3 {count},
etc.
},
IP2: {
Message1 {count},
Message2 {count},
Message3 {count},
etc.
},
etc.
}.
我只是被困在获取这些信息,并将其放入字典字典中,每条消息都有一个计数。
我有一个基本的工作原型,它存储 {IP1: {message1}、IP2: {message2} 等},但如果数字已经在字典中,它不会存储其他消息。我正在使用正则表达式过滤掉噪音,只关注信号(我需要的),它没有任何问题。但是我被数据结构部分所束缚,并且对消息进行计数。
我尝试过的
Create nested dictionary on the fly in Python
https://www.youtube.com/watch?v=ygRINYibL74
How do you create nested dict in Python?
https://www.youtube.com/watch?v=K8L6KVGG-7o
https://www.youtube.com/watch?v=c9HbsUSWilw
https://medium.com/factory-mind/regex-tutorial-a-simple-cheatsheet-by-examples-649dc1c3f285
https://docs.python.org/2/library/re.html
我尝试创建一个 pandas 数组和 numpy 数组,但它仍然对我不起作用。我使用了许多我没有添加书签的其他来源,试图帮助我,但我记不住它们。
示例代码
def cleanData(rawData):
cleanIP = ipSubstitution(rawData)
cleanPacket = packetSubstitution(cleanIP)
cleanMessage = messageSubstitution(cleanPacket)
cleanRepeats = repeatedSubstition(cleanMessage)
cleanHexadecimal = hexadecimalSubstition(cleanRepeats)
cleanTime = removeTime(cleanHexadecimal)
return cleanTime
def ipSubstitution(ip):
ip_exchange = re.compile(r"[a-z]{2,4}=[0-9]{0,3}.[0-9]{0,3}.[0-9]{0,3}.[0-9]{0,3}")
replaceIP = "XXX.XXX.XXX.XXX"
ipReturn = re.sub(ip_exchange, replaceIP, ip)
return ipReturn
def packetSubstitution(packet):
packetSubstitute = re.compile(r"[a-z]{2,4}_[a-z]{2,4}_[a-z]{2,4}_[a-z]{2,4}_[a-z]{2,4}")
replacePacket = "XX_XX_XXX_XXXX_XXX"
packetReturn = re.sub(packetSubstitute, replacePacket, packet)
return packetReturn
def messageSubstitution(message):
messageExchange = re.compile(r"[a-z]{0,5}_[a-z]{0,5}_[a-z]{0,5}_[a-z]{0,5}_[a-z]{0,5}.+")
replaceMessage = "XX_XXX_XXXXX_XXXXX_XXXXX"
messageReturn = re.sub(messageExchange, replaceMessage, message)
return messageReturn
def repeatedSubstition(repeatedMessage):
repeatedExchange = re.compile(r"[a-z]{7}\s[a-z]{8}.+")
replaceRepeated = "XXXXXXX"
repeatedReturn = re.sub(repeatedExchange, replaceRepeated, repeatedMessage)
return repeatedReturn
def hexadecimalSubstition(hexadecimalMessage):
hexadecimalExchange = re.compile(r"[a-z0-9]{12}\s[ok]{2}")
replaceHexadecimal = "XXXXXXXXXXXX"
hexadecimalReturn = re.sub(hexadecimalExchange, replaceHexadecimal, hexadecimalMessage)
return hexadecimalReturn
def removeTime(timeRemoval):
timeExchange = re.compile(r"([A-Z][a-z][a-z]\s\d{2})+\s+(\d{2}\:\d{2}\:\d{2})+\s")
replaceTime = ""
timeReturn = re.sub(timeExchange, replaceTime, timeRemoval)
return timeReturn
def matchExpression(analysisDict,rawText):
d = analysisDict
regexMatch = re.compile(
r"(?P<IP_Address>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:)+\s" +
"(?P<Message>.+)")
matchedText = re.match(regexMatch, rawText)
for _ in rawText:
count = 0
ip = matchedText.group("IP_Address")
message = matchedText.group("Message")
d.setdefault(ip, {})["Message"] = message
d[ip][message] = count + 1
// wanting to add count here but given an error regarding
// string can not hold variable
for doe in d:
if numbers == d[doe]:
for ray in d[doe]:
if message == d[doe][ray]:
d[doe][ray] = count + 1
analysisDict = {}
textFile = open('text_file', 'r')
for line in textFile:
//cleanData is a function calling other functions to
//clear away unneeded text
cleanData(line)
matchExpression(analysisDict,cleanData(line))
我一直在弄清楚如何将多个消息添加到每个数字,并将计数添加到每个消息。
如果有人可以帮助我,我将非常感激。
2019 年 8 月 18 日更新
示例输入
Jan 29 05:23:11 11.111.11.111: devmgmt: ah_tv_alg_proc_pkt: Packet(src=10.45.27.220, dst=69.25.139.140) dropped
Jan 29 05:23:11 11.111.11.111: devmgmt: ah_tv_alg_proc_pkt: Packet(src=10.45.27.89, dst=69.25.139.140) dropped
Jan 29 05:23:11 22.222.22.222: system: Fetch shared memory 1000 of size 182224, address at 0xb6254000
Jan 29 05:23:11 11.111.11.111: message repeated 8 times
Jan 29 05:23:11 11.111.11.111: devmgmt: ah_tv_alg_proc_pkt: Packet(src=10.45.27.231, dst=69.25.139.140) dropped
Jan 29 05:23:11 22.222.22.222: security: Admin "<admin>" successfully logged in
Jan 29 05:23:11 11.111.11.111: message repeated 15 times
Jan 29 05:23:11 11.111.11.111: devmgmt: ah_tv_alg_proc_pkt: Packet(src=10.45.27.220, dst=69.25.139.140) dropped
Jan 29 05:23:11 11.111.11.111: devmgmt: ah_tv_alg_proc_pkt: Packet(src=10.45.27.231, dst=69.25.139.140) dropped
Jan 29 05:23:11 11.111.11.111: devmgmt: ah_tv_alg_proc_pkt: Packet(src=10.45.27.217, dst=69.25.139.140) dropped
Jan 29 05:23:11 11.111.11.111: devmgmt: ah_tv_alg_proc_pkt: Packet(src=10.45.27.231, dst=69.25.139.140) dropped
Jan 29 05:23:11 22.222.22.222: security: admin:<save config current http://11.11.130.145:0000/run-config>
正则表达式之后
"IP1: Message"
"IP2: Message"
"IP1: different message"
"IP2: different message"
etc.
我需要什么帮助
-
每个 IP 地址存储多条消息(目前仅保存一条)
for _ in rawText: count = 0 ip = matchedText.group("IP_Address") message = matchedText.group("Message") d.setdefault(ip, {})["Message"] = message d[ip][message] = count + 1 // wanting to add count here but given an error regarding // string can not hold variable -
为每条消息制作一个子字典并存储它们的个人计数
for doe in d: if ip == d[doe]: for ray in d[doe]: if message == d[doe][ray]: d[doe][ray] = count + 1
预期输出
{
Number1: {
message1: {count1},
message2: {count2}
},
Number2: {
message1: {count1},
message2: {count2}
},
etc.
}
实际输出
{'xxx.xxx.xxx.xxx:': {'Message': '...: XX_XX_XXX_XXXX_XXX: Packet(XXX.XXX.XXX.XXX, XXX.XXX.XXX.XXX) dropped'}, 'xxx.xxx.xxx.xxx:': {'Message': '...: admin:<save config current http://xxx.xxx.xxx.xxx:xxxx/zzz-zzzzzz>'}, 'xxx.xxx.xxx.xxx:': {'Message': '...: arbitrator ip is updated from xxx.xxx.xxx.xxx to xxx.xxx.xxx.xxx'}, 'xxx.xxx.xxx.xxx:': {'Message': '[...]: XX_XXX_XXXXX_XXXXX_XXXXX'}, 'xxx.xxx.xxx.xxx:': {'Message': 'application: get ... cancel.'}}
最终更新
看了更多视频后,我只是在追加到数组时使用了 .split(":", 1) 函数,然后创建了一个 Pandas Dataframe,最后添加了一个带有计数的列。从那里,我对我试图解决的问题进行了必要的分析。希望这对以后的其他人有所帮助!
【问题讨论】:
-
现在看起来你的 atom 是
"Number(\d+):Message([^"]*)"你能验证一下吗?听着,除非您显示实际的输入样本,否则没有人会帮助您.. -
我用更清晰的输出编辑了它。问题不在于我的正则表达式,因为我知道它正在获取正确的数据,我的问题是将数据存储到字典中。
-
我刚刚向您展示了 atom 的概念。它是您一次需要提取的最小数据块,以便完整输入,我不在乎您有多少四重嵌套数组。忘记正则表达式,专注于进行完整的单一数据事务所需的数据。但是,最低限度,需要。相信我,数组很简单。您可能会在循环中获取数据,在其中处理匹配的每个事务。或者,您可以获取所有匹配项 findall() 并稍后在循环中处理它们。
-
啊,好吧,我很抱歉我不知道原子是什么(谢谢你的澄清)。附加到数组时,我确实获得了所有数据,但我正在尝试制作字典,因为它们似乎更易于数据访问和分析。与数组相比,您必须将 NumberX 与 MessageY 匹配(如果使用两个不同的数组)。从长远来看,我在考虑,这就是为什么我希望将每条消息的计数存储到字典中,与数字匹配。
-
如果没有完整的(可执行的)代码和可以运行的示例输入,我发现这很难理解。您有一些关于数字和消息的散文,然后是一些带有 IP 地址、“doe”和“ray”的代码,然后是示例输出(在一行上格式化!),其中的字符串没有出现在问题的其他任何地方......还有您能否简化代码以专注于您需要帮助的部分?
标签: python regex string dictionary nested