Алекс упоминал Pyparsing и так вот Pyparsing подход к вашей же проблема:
from pyparsing import Word, Suppress, Regex, oneOf, SkipTo
import datetime
DASHES = Word('-').suppress()
LPAR,RPAR,AT = map(Suppress,"()@")
date = Regex(r'\d{2}/\d{2}/\d{4}')
time = Regex(r'\d{2}:\d{2}:\d{2}')
status = oneOf("Busy Available Idle Offline Unavailable")
statechange1 = 'changed status from' + status('fromstate') + 'to' + status('tostate')
statechange2 = 'became' + status('tostate')
linefmt = (DASHES + SkipTo('(')('name') + LPAR + SkipTo(RPAR)('email') + RPAR +
(statechange1 | statechange2) +
AT + date('date') + time('time') + DASHES)
def convertFields(tokens):
if 'fromstate' not in tokens:
tokens['fromstate'] = 'NULL'
tokens['name'] = tokens.name.strip()
tokens['email'] = tokens.email.strip()
d,mon,yr = map(int, tokens.date.split('/'))
h,m,s = map(int, tokens.time.split(':'))
tokens['datetime'] = datetime.datetime(yr, mon, d, h, m, s)
linefmt.setParseAction(convertFields)
for line in text.splitlines():
fields = linefmt.parseString(line)
print "%(name)s/%(email)s %(fromstate)-10.10s %(tostate)-10.10s %(datetime)s" % fields
печатает:
Mark Grey/[email protected] Busy Available 2010-07-14 16:32:36
Silvia Pablo/[email protected] NULL Available 2010-07-14 16:32:39
Pyparsing позволяет присоединять имена полей результатов (так же, как по имени группы в ответе RE-style от Tom Pietzcker), а также действия разбора во времени для действий или обработки анализируемых действий - обратите внимание на преобразование отдельных полей даты и времени в настоящий объект datetime, уже преобразованный и готовый к обработке после синтаксического анализа без дополнительный muss n или суета.
Вот модифицированный цикл, который только дампы из разобранных жетоны и именованные поля для каждой строки:
for line in text.splitlines():
fields = linefmt.parseString(line)
print fields.dump()
печатает:
['Mark Grey ', '[email protected]', 'changed status from', 'Busy', 'to', 'Available', '14/07/2010', '16:32:36']
- date: 14/07/2010
- datetime: 2010-07-14 16:32:36
- email: [email protected]
- fromstate: Busy
- name: Mark Grey
- time: 16:32:36
- tostate: Available
['Silvia Pablo ', '[email protected]', 'became', 'Available', '14/07/2010', '16:32:39']
- date: 14/07/2010
- datetime: 2010-07-14 16:32:39
- email: [email protected]
- fromstate: NULL
- name: Silvia Pablo
- time: 16:32:39
- tostate: Available
Я подозреваю, что, как вы будете продолжать работать над этим проблема, вы найдете другие варианты формата входного текста, определяющие изменение состояния пользователя. В этом случае вы просто добавите другое определение, например statechange1
или statechange2
, и вставьте его в linefmt
с остальными. Я чувствую, что структурирование pyparsing определения парсера помогает разработчикам вернуться к парсеру после того, как все изменилось, и легко расширить свою программу синтаксического анализа.
NaN ........... –
Ну, это не число хорошо :) –
EDIT Примечание: Марсело и Тим дал вам довольно хороший ответ на то, что вы хотите сделать. Вот документация для библиотеки регулярных выражений, включенная в Python, которая может помочь вам расширить код: http://docs.python.org/library/re.html –