从文件中提取子字符串

时间:2015-10-08 11:19:46

标签: python

我有一个巨大的日志文件,我必须从中提取特定的模式或字节数组。 每一行看起来像这样:

<<< 10:39:01.296  [0x01|0x02|0x04|0x05] [0x00|0xDE|0xAD]   (Value: Check)

从这一行我必须提取字节0xDE和0xAD。

日志模式通常是形式(只有XX和YY是变体):

<<< 10:39:01.296  [0x01|0x02|0x04|0x05] [0x00|0xXX|0xYY]   (Value: Check)

要试用,我将此模式作为字符串并使用以下代码进行检查。但是我觉得必须有比这更好的方法。你能告诉我吗?

input= """<<< 10:39:01.296  [0x01|0x02|0x04|0x05] [0x00|0xDE|0xAD]   (Value: Check) """

#extract 0xDE and 0xAD and join them to read DEAD


c = input.find("]")
d = input.find('[', c)
e = input.find("]", d)
mystr =  input[d+6:e]
x,y = mystr.split('|0x', 1)

print x
print y
numStr =  ''.join(mystr.split('|0x', 1))


print numStr
#val = int(numStr,16)
#print val:

4 个答案:

答案 0 :(得分:0)

如果格式在第二个块中总是有三个字节,那么第一个块永远不会有三个字节,你只关心块的后两个字节,那么这里有几个方法。

一种方法是通过从右侧开始搜索并使用异常提升搜索方法来简化对相关块的搜索(因此您不需要明确检查返回值以查看{{1成功,只是find / try并跳过该行,如果它没有预期的数据):

except

mystr = input[input.rindex('[')+1:input.rindex(']')] byteparts = mystr.split('|') byte1, byte2 = byteparts[1:] # Unlike the above, this keeps the 0x, but that's trivially stripped if you care # By using [1:] as the slice and unpacking the result, if you got a set # of matches that isn't three bytes long, you'll get an exception on unpack 的使用意味着你可以忽略第一个块(你永远不会得到它),如果搜索失败,它会立即引发错误而不是返回-1并且默默地行为不端。

另一个解决方案是使用正则表达式(我不情愿地说这个;很多人将正则表达式作为第一手段,这通常是一个坏主意,但对于足够奇怪的情况,有时比构建逻辑更好来自方法调用)。这将解决所述问题,并可通过调整正则表达式来处理更复杂的变体:

rindex

答案 1 :(得分:0)

如果你不想使用正则表达式,并且你的日志模式总是看起来像你的样本,你可以做一个丑陋的单行

print ''.join(item.replace('0x', '') for item in input.split('[')[2].split(']')[0].split('|')[1:])
>>> 'DEAD'

答案 2 :(得分:0)

如上所述的问题,以下内容将输出您想要的内容,但不知何故,我感觉您的问题不是它看起来的东西,并且缺少一些重要的东西。

>>> res = ''.join(input[46:55].split('|0x',1)).split('0x',1)[1]
>>> if res == 'DEAD': print res
... 
DEAD

或如何:

>>> input= "<<< 10:39:01.296  [0x01|0x02|0x04|0x05] [0x00|0xDE|0xAD]   (Value: Check) "
>>> if '|0xDE|0xAD]' in input:
...     print "DEAD occurred at ", input[4:16]
... 
DEAD occurred at  10:39:01.296

或:

>>> if input.rfind('|0xDE|0xAD]') > 40:
...     print "DEAD occurred at ", input[4:16]
... 
DEAD occurred at  10:39:01.296

答案 3 :(得分:0)

最后两个数字可以如下提取:

import re

text = "<<< 10:39:01.296  [0x01|0x02|0x04|0x05] [0x00|0xDE|0xAD]   (Value: Check)"
parts = re.split(r'[|\]]', text)

print int(parts[-3], 16)
print int(parts[-2], 16)

,并提供:

222
173

注意:最好不要使用名为input的变量,因为这是内置的Python函数。