Токенизация строки с неравным количеством пробелов между полями - PullRequest
1 голос
/ 02 января 2011

Я пытаюсь токенизировать записи из файла.Однако я не могу использовать параметр line.split("") из-за неравного количества пробелов между файлами.Я копирую несколько строк из моего файла ниже:

"08-09-2010 21:21:46      00:22:7f:a6:9b:69                                 -79"
"08-09-2010 21:21:46      04:4f:aa:b4:49:49                                 -79"
"08-09-2010 21:21:46      04:4f:aa:31:4e:59   tikona 18002090044            -83"
"08-09-2010 21:21:46      00:22:7f:26:9b:69   tikona 18002090044            -74"
"08-09-2010 21:21:46      04:4f:aa:34:0d:c9   tikona 18002090044            -82"
"08-09-2010 21:21:46      04:4f:aa:71:4e:59                                 -85"
"08-09-2010 21:21:46      04:4f:aa:34:21:89   tikona 18002090044            -75"
"08-09-2010 21:21:46      04:4f:aa:34:49:49   tikona 18002090044            -77"
"08-09-2010 21:21:46      04:4f:aa:74:0d:c9                                 -85"
"08-09-2010 21:22:47      18 APs were seen
"

Мне нужен доступ к первому столбцу (который является datetime объектом), второму столбцу (00:22...) и последнему столбцу (-79 и т. Д.).У меня нет проблем с доступом к первому и второму столбцам, но не к последнему столбцу.Когда я делаю info=line.spilt(""), так как в третьем столбце может быть или не быть записей, я не могу определить номер токена.

Как получить доступ к 4-му столбцу?Есть ли способ, которым я могу использовать info[i].contains(" -")?

Ответы [ 4 ]

7 голосов
/ 02 января 2011

Столбцы выглядят с фиксированной шириной, в этом случае вы можете использовать нарезку строк с последующим возможным .strip() для удаления конечных пробелов:

>>> for line in data.split('\n'):
...     print (line[1:25].strip(), line[26:45].strip(), line[46:69].strip(), line[70:-1].strip())
... 
('08-09-2010 21:21:46', '00:22:7f:a6:9b:69', '', '-79')
('08-09-2010 21:21:46', '04:4f:aa:b4:49:49', '', '-79')
('08-09-2010 21:21:46', '04:4f:aa:31:4e:59', 'tikona 18002090044', '-83')
('08-09-2010 21:21:46', '00:22:7f:26:9b:69', 'tikona 18002090044', '-74')
('08-09-2010 21:21:46', '04:4f:aa:34:0d:c9', 'tikona 18002090044', '-82')
('08-09-2010 21:21:46', '04:4f:aa:71:4e:59', '', '-85')
('08-09-2010 21:21:46', '04:4f:aa:34:21:89', 'tikona 18002090044', '-75')
('08-09-2010 21:21:46', '04:4f:aa:34:49:49', 'tikona 18002090044', '-77')
('08-09-2010 21:21:46', '04:4f:aa:74:0d:c9', '', '-85')
('08-09-2010 21:22:47', '18 APs were seen', '', '')
('', '', '', '')

('', '', '', '') происходит от последней строки ввода, являющейся".

Если столбцы не фиксированной ширины, то вы все равно можете использовать .split() и получить столбец последний , используя индекс -1,Хотя вы должны использовать .split() с осторожностью, так как это делается неправильно, когда все сделано "правильно".Я рекомендую использовать двойной пробел в качестве разделителя для обработки случая 18 APs were seen, но учтите, что это меняет индекс для второго столбца.

>>> for line in data.split('\n'):
...     fields = line.split('  ')
...     print (fields[0], fields[3], fields[-1])
... 
('"08-09-2010 21:21:46', '00:22:7f:a6:9b:69', ' -79"')
('"08-09-2010 21:21:46', '04:4f:aa:b4:49:49', ' -79"')
('"08-09-2010 21:21:46', '04:4f:aa:31:4e:59', '-83"')
('"08-09-2010 21:21:46', '00:22:7f:26:9b:69', '-74"')
('"08-09-2010 21:21:46', '04:4f:aa:34:0d:c9', '-82"')
('"08-09-2010 21:21:46', '04:4f:aa:71:4e:59', ' -85"')
('"08-09-2010 21:21:46', '04:4f:aa:34:21:89', '-75"')
('"08-09-2010 21:21:46', '04:4f:aa:34:49:49', '-77"')
('"08-09-2010 21:21:46', '04:4f:aa:74:0d:c9', ' -85"')
('"08-09-2010 21:22:47', '18 APs were seen', '18 APs were seen')
('"08-09-2010 21:21:46', '00:22:7f:26:9b:69', '-74"')
Traceback (most recent call last):
  File "<input>", line 3, in <module>
IndexError: list index out of range

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

1 голос
/ 02 января 2011

Вы можете разделить его с помощью регулярного выражения,

#!/usr/bin/env python

import re

mac_data_re = re.compile(
    r'^(?P<date>[\d-]+)\s+' +
    r'(?P<time>[\d:]+)\s+' +
    r'(?P<mac>[\da-f:]+)\s+' +
    r'(?P<host>\w+){0,1}\s+' +
    r'(?P<host_id>\d+){0,1}\s+'
    r'(?P<final_number>-{0,1}\d+)$')

with file('list') as f:
    for line in (l.strip() for l in f):
        match = mac_data_re.match(line)
        if match:
            print "date={date}, time={time}, mac={mac}, host={host}, host_id={host_id} final_number={final_number}".format(**match.groupdict())
        else:
            print "Line not matched: '%s'" % line

Вот вывод,

 aid@bullet:~/tmp$ ./parse_list.py 
date=08-09-2010, time=21:21:46, mac=00:22:7f:a6:9b:69, host=None, host_id=None final_number=-79
date=08-09-2010, time=21:21:46, mac=04:4f:aa:b4:49:49, host=None, host_id=None final_number=-79
date=08-09-2010, time=21:21:46, mac=04:4f:aa:31:4e:59, host=tikona, host_id=18002090044 final_number=-83
date=08-09-2010, time=21:21:46, mac=00:22:7f:26:9b:69, host=tikona, host_id=18002090044 final_number=-74
date=08-09-2010, time=21:21:46, mac=04:4f:aa:34:0d:c9, host=tikona, host_id=18002090044 final_number=-82
date=08-09-2010, time=21:21:46, mac=04:4f:aa:71:4e:59, host=None, host_id=None final_number=-85
date=08-09-2010, time=21:21:46, mac=04:4f:aa:34:21:89, host=tikona, host_id=18002090044 final_number=-75
date=08-09-2010, time=21:21:46, mac=04:4f:aa:34:49:49, host=tikona, host_id=18002090044 final_number=-77
date=08-09-2010, time=21:21:46, mac=04:4f:aa:74:0d:c9, host=None, host_id=None final_number=-85
Line not matched: '08-09-2010 21:22:47      18 APs were seen'
0 голосов
/ 02 января 2011

У вас есть контроль над кодом, который записывает этот файл?Если это так, вы можете изменить его, чтобы использовать поля с разделителями табуляции, а затем разделить на вкладки.Это будет поддерживать последовательное разделение полей.

0 голосов
/ 02 января 2011

Вы можете rsplit, чтобы получить последнее значение, что-то вроде "" .rsplit ("", 1)

...