2013-02-21 3 views
1

У меня есть следующий файл, который будет проанализирован:Как правильно разбить следующую строку? - Python

Total Virtual Clients  :    10  (1 Machines) 
Current Connections   :    10 
Total Elapsed Time   :    50 Secs (0 Hrs,0 Mins,50 Secs) 

Total Requests    :   337827  ( 6687/Sec) 
Total Responses    :   337830  ( 6687/Sec) 
Total Bytes     :  990388848  ( 20571 KB/Sec) 
Total Success Connections :   3346  (  66/Sec) 
Total Connect Errors  :    0  (  0/Sec) 
Total Socket Errors   :    0  (  0/Sec) 
Total I/O Errors   :    0  (  0/Sec) 
Total 200 OK    :   33864  ( 718/Sec) 
Total 30X Redirect   :    0  (  0/Sec) 
Total 304 Not Modified  :    0  (  0/Sec) 
Total 404 Not Found   :   303966  ( 5969/Sec) 
Total 500 Server Error  :    0  (  0/Sec) 
Total Bad Status   :   303966  ( 5969/Sec) 

поэтому у меня есть алгоритм синтаксического анализа для поиска файлов для этих значений, однако, когда я делаю:

for data in temp: 
    line = data.strip().split() 
    print line 

где temp является мой временный буфер, который содержит эти ценности, я получаю:

['Total', 'I/O', 'Errors', ':', '0', '(', '0/Sec)'] 
['Total', '200', 'OK', ':', '69807', '(', '864/Sec)'] 
['Total', '30X', 'Redirect', ':', '0', '(', '0/Sec)'] 
['Total', '304', 'Not', 'Modified', ':', '0', '(', '0/Sec)'] 
['Total', '404', 'Not', 'Found', ':', '420953', '(', '5289/Sec)'] 
['Total', '500', 'Server', 'Error', ':', '0', '(', '0/Sec)'] 

и я хотел:

['Total I/O Errors', '0', '0'] 
['Total 200 OK', '69807', '864'] 
['Total 30X Redirect', '0', '0'] 

и так далее. Как я мог это сделать?

ответ

4

Вы можете использовать regular expression следующим образом:

import re 
rex = re.compile('([^:]+\S)\s*:\s*(\d+)\s*\(\s*(\d+)/Sec\)') 
for line in temp: 
    match = rex.match(line) 
    if match: 
     print match.groups() 

, который даст вам:

['Total Requests', '337827', '6687'] 
['Total Responses', '337830', '6687'] 
['Total Success Connections', '3346', '66'] 
['Total Connect Errors', '0', '0'] 
['Total Socket Errors', '0', '0'] 
['Total I/O Errors', '0', '0'] 
['Total 200 OK', '33864', '718'] 
['Total 30X Redirect', '0', '0'] 
['Total 304 Not Modified', '0', '0'] 
['Total 404 Not Found', '303966', '5969'] 
['Total 500 Server Error', '0', '0'] 
['Total Bad Status', '303966', '5969'] 

Обратите внимание, что будет соответствовать только строки, которые соответствуют "TITLE: NUMBER (ЧИСЛО/сек)" , Вы можете адаптировать выражение для соответствия другим строкам.

+0

Это классный человек! Спасибо! (будет приниматься ваш ответ в нескольких случаях) – cybertextron

0

Вместо разделения на пробельных, вам нужно будет разделить на основе других разделителей в вашем формате, это может выглядеть примерно так:

for data in temp: 
    first, rest = data.split(':') 
    second, rest = rest.split('(') 
    third, rest = rest.split(')') 
    print [x.strip() for x in (first, second, third)] 
+0

Данные представляют собой фиксированную ширину поля, поэтому было бы лучше использовать фиксированную разрезку –

1

регулярные выражения являются избыточна для разбора данных, но это удобный способ выражения полей фиксированной длины. Например,

for data in temp: 
    first, second, third = re.match("(.{28}):(.{21})(.*)", data).groups() 
    ... 

Это означает, что первое поле - 28 символов. Пропустить ':', следующие 21 символ - второе поле, остальное - 3-е поле