Разбор в python вызывает исключение - PullRequest
0 голосов
/ 07 ноября 2018

Я использовал приведенный ниже код для синтаксического анализа журнала сервера в python, используя pyparsing, и я получил исключение. Похоже, грамматика верна, поскольку она работает для одной строки журнала, но почему я вижу это исключение? Спасибо за любые указатели или руководство!

#!/bin/python

# import required modules
# (include the ones used later after defining grammar)
import string
from pyparsing import alphas, nums, Combine, Word, Group, 
delimitedList, Suppress, removeQuotes, alphanums

test_data = """
Oct 31 06:26:51 os-test-rb dhclient[844]: DHCPACK of 192.168.14.6 
from 192.168.14.2
"""
# define a function with the grammar

logLine = None
def getLog():
    global logLine

    if logLine is None:
        serverDateTime = Combine(Word(alphas) + Word(nums) + 
                          Word(nums) + ":" + Word(nums) + ":" + Word(nums))
        userName = Word(alphas+'-')
        clientName = Combine(Word(alphas) +"[" + Word(nums) + "]" + ":")
        message = Word(alphanums) + Word(alphas) + delimitedList( Word(nums), ".", combine=True ) + Word(alphas) + delimitedList( Word(nums), ".", combine=True )

        logLine = ( serverDateTime.setResultsName("timestamp") +
            userName.setResultsName("username") +
            clientName.setResultsName("client") +
            message.setResultsName("Message from Server"))

        return logLine

  # print out the log

for line in test_data:
    if not line: continue
    data = getLog().parseString(line)
    print(data.dump())
    print(data.asXML("LOG"))

Исключение составляет:

Traceback (most recent call last):
  File "server_log_parser1.py", line 63, in <module>
    data = getLog().parseString(line)

    raise ParseException(instring, loc, self.errmsg, self)
pyparsing.ParseException: Expected W:(ABCD...) (at char 1), (line:2, col:1)

1 Ответ

0 голосов
/ 07 ноября 2018

Мое первое предположение состоит в том, что вы анализируете строку, содержащую только пробел, или, возможно, просто завершающий перевод строки. Ваш фильтр if line: continue не поймает этого, поэтому вы передаете по существу пустую строку в pyparsing, которая затем жалуется, что нет времени ведущей даты (фактически нет строки начального месяца, состоящей из слова альфа). Измените эту строку на:

     if not line.strip(): continue

Кроме того, я бы посоветовал вам отказаться от использования asXML() в пользу dump(). asXML() делает некоторые догадки, которыми я никогда не был доволен, и мне, как правило, не нравится интерфейс, поэтому он устарел и будет удален в следующем минорном выпуске. dump() гораздо лучше перечислять как безымянные, так и именованные токены и списки. Кроме того, использование expr.runTests() очень полезно для лучшей диагностики того, где парсеры сбиваются с пути.

...