pyparsing: группировать текст между датами - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть файлы журналов, которые содержат дату / время с различным числом строк между следующей датой / временем

ex.

время-дата
2/07/1813: 55: 00.983

msecVal = pyparsing.Word(pyparsing.nums, max=3)
numPair = pyparsing.Word(pyparsing.nums, exact=2)
dateStr = pyparsing.Combine(numPair + '/' + numPair + '/' + numPair)

timeString = pyparsing.Combine(numPair + ':' + numPair + ':' +     numPair\               
       + '.' + msecVal)

файл журнала будет

time:date:  line of text
    possible 2nd line of text
    possible 3rd line of text...
    time:date:  line of text
time:date: line of text
    possible 2nd line of text
    possible 3rd line of text...
    possible <n> line of text...
time:date:  line of text

На вход будет большой текстовый файл журнала в указанном формате.Я хотел бы создать список сгруппированных элементов

[[time],[all text until next time]],[[time],[all text until next time]...

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

1 Ответ

0 голосов
/ 14 декабря 2018

Вот как я интерпретирую ваше определение записи в журнале:

"Дата-время в начале строки, за которой следует двоеточие, за которым следует все до следующей даты-времени вначало строки, даже если в строку могут быть встроены даты и время. "

Для решения этой проблемы необходимо решить две проблемы:

  • LineStart- различать дату и время в начале строки от даты в теле строки

  • SkipTo - быстрый способ пропустить неструктурированный текст до тех пор, пока не будет найдено соответствующее выражение

Я добавил эти выражения в ваш код (я импортировал pyparsing как 'pp', потому что я ленивый машинистка):

dateTime = dateStr + timeString

# log entry date-time keys only match if they are at the start of the line
dateTimeKey = pp.LineStart() + dateTime

# define a log entry as a date-time key, followed by everything up to the next 
# date-time key, or to the end of the input string
# (use results names to make it easy to get at the parts of the log entry)
logEntry = pp.Group(dateTimeKey("time") + ':' + pp.Empty()
                    + pp.SkipTo(dateTimeKey | pp.StringEnd())("body"))

Я преобразовал ваш пример, чтобы иметь другое время датыв нем для тестирования, и мы получаем это:

sample = """\
2/07/18 13:55:00.983:  line of text
    possible 2nd line of text
    possible 3rd line of text...
    2/07/19 13:55:00.983:  line of text
2/07/20 13:55:00.983: line of text
    possible 2nd line of text
    possible 3rd line of text...
    possible <n> line of text...
2/07/21 13:55:00.983:  line of text
"""

print(pp.OneOrMore(logEntry).parseString(sample).dump())

Дает:

[['2/07/18', '13:55:00.983', ':', 'line of text\n    possible 2nd line of text\n    possible 3rd line of text...\n    2/07/19 13:55:00.983:  line of text'], ['2/07/20', '13:55:00.983', ':', 'line of text\n    possible 2nd line of text\n    possible 3rd line of text...\n    possible <n> line of text...'], ['2/07/21', '13:55:00.983', ':', 'line of text']]
[0]:
  ['2/07/18', '13:55:00.983', ':', 'line of text\n    possible 2nd line of text\n    possible 3rd line of text...\n    2/07/19 13:55:00.983:  line of text']
  - body: 'line of text\n    possible 2nd line of text\n    possible 3rd line of text...\n    2/07/19 13:55:00.983:  line of text'
  - time: ['2/07/18', '13:55:00.983']
[1]:
  ['2/07/20', '13:55:00.983', ':', 'line of text\n    possible 2nd line of text\n    possible 3rd line of text...\n    possible <n> line of text...']
  - body: 'line of text\n    possible 2nd line of text\n    possible 3rd line of text...\n    possible <n> line of text...'
  - time: ['2/07/20', '13:55:00.983']
[2]:
  ['2/07/21', '13:55:00.983', ':', 'line of text']
  - body: 'line of text'
  - time: ['2/07/21', '13:55:00.983']

Мне также пришлось преобразовать ваш num_pair в:

numPair = pp.Word(pp.nums, max=2)

иначе он не будет совпадать с первой цифрой 2 в вашей дате выборки.

...